openhab-scripting 4.47.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 -38
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "types"
4
+
5
+ Dir[File.expand_path("items/*.rb", __dir__)].sort.each do |f|
6
+ require f
7
+ end
8
+
9
+ module OpenHAB
10
+ module Core
11
+ #
12
+ # Contains the core types that openHAB uses to represent items.
13
+ # Items have states from the {Types} module.
14
+ #
15
+ # You may use an item or group name anywhere {DSL} (or just {Core::EntityLookup})
16
+ # is available, and it will automatically be loaded.
17
+ #
18
+ module Items
19
+ class << self
20
+ # Imports all of the item classes into the global namespace
21
+ # for convenient access.
22
+ def import_into_global_namespace
23
+ concrete_item_classes.each do |k|
24
+ const_name = k.java_class.simple_name
25
+ Object.const_set(const_name, k) unless Object.const_defined?(const_name)
26
+ end
27
+ Object.const_set(:GenericItem, GenericItem) unless Object.const_defined?(:GenericItem)
28
+ Object.const_set(:Item, Item) unless Object.const_defined?(:Item)
29
+ end
30
+
31
+ private
32
+
33
+ # takes an array of Type java classes and returns
34
+ # all the Enum values, in a flat array
35
+ def values_for_enums(enums)
36
+ enums.map(&:ruby_class)
37
+ .select { |k| k < java.lang.Enum }
38
+ .flat_map(&:values)
39
+ end
40
+
41
+ # define predicates for checking if an item is in one of the Enum states
42
+ def def_predicate_methods(klass)
43
+ values_for_enums(klass.ACCEPTED_DATA_TYPES).each do |state|
44
+ _command_predicate, state_predicate = Types::PREDICATE_ALIASES[state.to_s]
45
+ next if klass.instance_methods.include?(state_predicate)
46
+
47
+ logger.trace("Defining #{klass}##{state_predicate} for #{state}")
48
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
49
+ def #{state_predicate} # def on?
50
+ raw_state.as(#{state.class.java_class.simple_name}).equal?(#{state}) # raw_state.as(OnOffType) == ON
51
+ end # end
52
+ RUBY
53
+ end
54
+ end
55
+
56
+ # define methods for commanding an item to one of the Enum states
57
+ # as well as predicates for if an ItemCommandEvent is one of those commands
58
+ def def_command_methods(klass)
59
+ values_for_enums(klass.ACCEPTED_COMMAND_TYPES).each do |value|
60
+ command = Types::COMMAND_ALIASES[value.to_s]
61
+ next if klass.instance_methods.include?(command)
62
+
63
+ logger.trace("Defining #{klass}##{command} for #{value}")
64
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
65
+ ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def on(*args, &block)
66
+ command(#{value}, *args, &block) # command(ON, *args, &block)
67
+ end # end
68
+ RUBY
69
+
70
+ logger.trace("Defining Enumerable##{command} for #{value}")
71
+ Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
72
+ def #{command} # def on
73
+ each(&:#{command}) # each(&:on)
74
+ end # end
75
+ RUBY
76
+
77
+ logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
78
+ Events::ItemCommandEvent.class_eval <<~RUBY, __FILE__, __LINE__ + 1
79
+ def #{command}? # def refresh?
80
+ command.as(#{value.class.java_class.simple_name}).equal?(#{value}) # command.as(RefreshType).equal?(REFRESH)
81
+ end # end
82
+ RUBY
83
+ end
84
+ end
85
+
86
+ def concrete_item_classes
87
+ constants.map { |c| const_get(c) }
88
+ .grep(Module)
89
+ .select { |k| k < GenericItem }
90
+ end
91
+ end
92
+
93
+ # sort classes by hierarchy so we define methods on parent classes first
94
+ constants.map { |c| const_get(c) }
95
+ .grep(Module)
96
+ .select { |k| k <= GenericItem && k != GroupItem && k != StringItem }
97
+ .sort { |a, b| (a < b) ? 1 : -1 }
98
+ .each do |klass|
99
+ klass.field_reader :ACCEPTED_COMMAND_TYPES, :ACCEPTED_DATA_TYPES unless klass == GenericItem
100
+
101
+ def_predicate_methods(klass)
102
+ def_command_methods(klass)
103
+ end
104
+
105
+ prepend_accepted_data_types
106
+ end
107
+ end
108
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenHAB
4
- module DSL
4
+ module Core
5
5
  # Common base class for array-like collections that have lookup
6
6
  # methods to avoid instantiating the elements if you only use
7
7
  # the lookup method
@@ -11,6 +11,12 @@ module OpenHAB
11
11
  module LazyArray
12
12
  include Enumerable
13
13
 
14
+ # @!visibility private
15
+ def self.included(klass)
16
+ klass.undef_method :inspect
17
+ klass.undef_method :to_s
18
+ end
19
+
14
20
  # Calls the given block once for each object, passing that object as a
15
21
  # parameter. Returns self.
16
22
  #
@@ -30,14 +36,14 @@ module OpenHAB
30
36
 
31
37
  # Delegate any other methods to the actual array, exclude mutating methods
32
38
  def method_missing(method, *args, &block)
33
- return to_a.send(method, *args, &block) if method[-1] != '!' && Array.instance_methods.include?(method)
39
+ return to_a.send(method, *args, &block) if method[-1] != "!" && Array.instance_methods.include?(method)
34
40
 
35
41
  super
36
42
  end
37
43
 
38
44
  # @!visibility private
39
45
  def respond_to_missing?(method, include_private = false)
40
- return true if method[-1] != '!' && Array.instance_methods.include?(method.to_sym)
46
+ return true if method[-1] != "!" && Array.instance_methods.include?(method.to_sym)
41
47
 
42
48
  super
43
49
  end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ require_relative "script_handling"
6
+
7
+ module OpenHAB
8
+ module Core
9
+ # @!visibility private
10
+ class ProfileFactory
11
+ include org.openhab.core.thing.profiles.ProfileFactory
12
+ include Singleton
13
+
14
+ # rubocop:disable Naming/MethodName
15
+ class Profile
16
+ include org.openhab.core.thing.profiles.StateProfile
17
+
18
+ def initialize(callback, context, uid, thread_locals, block)
19
+ unless callback.class.ancestors.include?(Things::ProfileCallback)
20
+ callback.class.prepend(Things::ProfileCallback)
21
+ callback.class.field_reader :link
22
+ end
23
+
24
+ @callback = callback
25
+ @context = context
26
+ @uid = uid
27
+ @thread_locals = thread_locals
28
+ @block = block
29
+ end
30
+
31
+ # @!visibility private
32
+ def getProfileTypeUID
33
+ @uid
34
+ end
35
+
36
+ # @!visibility private
37
+ def onCommandFromItem(command)
38
+ return unless process_event(:command_from_item, command: command) == true
39
+
40
+ logger.trace("Forwarding original command")
41
+ @callback.handle_command(command)
42
+ end
43
+
44
+ # @!visibility private
45
+ def onStateUpdateFromHandler(state)
46
+ return unless process_event(:state_from_handler, state: state) == true
47
+
48
+ logger.trace("Forwarding original update")
49
+ @callback.send_update(state)
50
+ end
51
+
52
+ # @!visibility private
53
+ def onCommandFromHandler(command)
54
+ return unless process_event(:command_from_handler, command: command) == true
55
+
56
+ logger.trace("Forwarding original command")
57
+ callback.send_command(command)
58
+ end
59
+
60
+ # @!visibility private
61
+ def onStateUpdateFromItem(state)
62
+ process_event(:state_from_item, state: state)
63
+ end
64
+
65
+ private
66
+
67
+ def process_event(event, **params)
68
+ logger.trace("Handling event #{event.inspect} in profile #{@uid} with param #{params.values.first.inspect}.")
69
+
70
+ params[:callback] = @callback
71
+ params[:context] = @context
72
+ params[:configuration] = @context.configuration.properties
73
+ params[:link] = @callback.link
74
+ params[:item] = @callback.link.item
75
+ params[:channel_uid] = @callback.link.linked_uid
76
+ params[:state] ||= nil
77
+ params[:command] ||= nil
78
+
79
+ kwargs = {}
80
+ @block.parameters.each do |(param_type, name)|
81
+ case param_type
82
+ when :keyreq, :key
83
+ kwargs[name] = params[name] if params.key?(name)
84
+ when :keyrest
85
+ kwargs = params
86
+ end
87
+ end
88
+
89
+ DSL::ThreadLocal.thread_local(**@thread_locals) do
90
+ @block.call(event, **kwargs)
91
+ rescue Exception => e
92
+ raise if defined?(::RSpec)
93
+
94
+ @block.binding.eval("self").logger.log_exception(e)
95
+ end
96
+ end
97
+ end
98
+ private_constant :Profile
99
+ # rubocop:enable Naming/MethodName
100
+
101
+ def initialize
102
+ @profiles = {}
103
+
104
+ @registration = OSGi.register_service(self)
105
+ ScriptHandling.script_unloaded { unregister }
106
+ end
107
+
108
+ #
109
+ # Unregister the ProfileFactory OSGi service
110
+ #
111
+ # @!visibility private
112
+ # @return [void]
113
+ #
114
+ def unregister
115
+ @registration.unregister
116
+ end
117
+
118
+ # @!visibility private
119
+ def register(uid, block)
120
+ @profiles[uid] = [DSL::ThreadLocal.persist, block]
121
+ end
122
+
123
+ def createProfile(type, callback, context) # rubocop:disable Naming/MethodName
124
+ @profiles[type].then { |(thread_locals, block)| Profile.new(callback, context, type, thread_locals, block) }
125
+ end
126
+
127
+ def getSupportedProfileTypeUIDs # rubocop:disable Naming/MethodName
128
+ @profiles.keys
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ # @interface
8
+ java_import org.openhab.core.common.registry.ManagedProvider
9
+
10
+ # @!visibility private
11
+ module ManagedProvider
12
+ # Maps actual element types to the symbol used in Thread.local[:openhab_providers]
13
+ TYPE_TO_PROVIDER_TYPE = {
14
+ org.openhab.core.items.Item.java_class => :items,
15
+ org.openhab.core.items.Metadata.java_class => :metadata,
16
+ org.openhab.core.automation.Rule.java_class => :rules,
17
+ org.openhab.core.thing.Thing.java_class => :things,
18
+ org.openhab.core.thing.link.ItemChannelLink.java_class => :links
19
+ }.freeze
20
+ private_constant :TYPE_TO_PROVIDER_TYPE
21
+
22
+ # @return [Symbol, nil]
23
+ def type
24
+ java_class.generic_ancestors.each do |klass|
25
+ next unless klass.respond_to?(:raw_type)
26
+ next unless klass.raw_type == org.openhab.core.common.registry.Provider.java_class
27
+
28
+ type_arg = klass.actual_type_arguments.first
29
+ next unless type_arg.is_a?(java.lang.Class)
30
+ next unless klass.actual_type_arguments.first.is_a?(java.lang.Class)
31
+
32
+ return TYPE_TO_PROVIDER_TYPE[type_arg]
33
+ end
34
+ nil
35
+ end
36
+ end
37
+
38
+ # @abstract
39
+ class Provider < org.openhab.core.common.registry.AbstractProvider
40
+ include org.openhab.core.common.registry.ManagedProvider
41
+ include Enumerable
42
+ include Singleton
43
+ public_class_method :new
44
+
45
+ # Known supported provider types
46
+ # @return [Array<Symbol>]
47
+ KNOWN_TYPES = %i[items metadata things links].freeze
48
+
49
+ class << self
50
+ #
51
+ # Determines the current provider that should be used to create elements belonging to this registry.
52
+ #
53
+ # @param [org.openhab.core.common.registry.Provider, Proc, :persistent, :transient, nil] preferred_provider
54
+ # An optional preferred provider to use. Can be one of several types:
55
+ # * An explicit instance of {org.openhab.core.common.registry.ManagedProvider ManagedProvider}
56
+ # * A Proc, which can calculate the preferred provider based on whatever conditions it wants,
57
+ # and then is further processed as this parameter.
58
+ # * `:persistent`, meaning the default {org.openhab.core.common.registry.ManagedProvider ManagedProvider}
59
+ # for this registry. Managed providers persist their objects to JSON, and will survive after the
60
+ # Ruby script is unloaded. This is where objects you configure with MainUI are stored. You should
61
+ # use this provider when you're creating something in response to a one-time event.
62
+ # * `:transient`, meaning a {org.openhab.core.common.registry.ManagedProvider ManagedProvider} that
63
+ # will remove all of its contents when the Ruby script is unloaded. You should use this if you're
64
+ # generating objects dynamically, either based on some sort of other configuration, or simply
65
+ # hard coded and you're using Ruby as a more expressive way to define things than a `.items` or
66
+ # `.things` file. If you _don't_ use this provider for something such as metadata, then you
67
+ # may have issues such as metadata still showing up even though you're no longer creating items
68
+ # with it anymore.
69
+ # * `nil`, meaning to fall back to the current thread setting. See {OpenHAB::DSL.provider}.
70
+ # If there is no thread setting (or the thread setting was Proc that returned `nil`),
71
+ # it defaults to `:transient`.
72
+ # @return [org.openhab.core.common.registry.Provider]
73
+ #
74
+ def current(preferred_provider = nil, element = nil)
75
+ preferred_provider ||= Thread.current[:openhab_providers]&.[](type)
76
+ if preferred_provider.is_a?(Proc)
77
+ preferred_provider = if preferred_provider.arity.zero? || element.nil?
78
+ preferred_provider.call
79
+ else
80
+ preferred_provider.call(element)
81
+ end
82
+ end
83
+
84
+ case preferred_provider
85
+ when nil, :transient
86
+ instance
87
+ when :persistent
88
+ registry.managed_provider.get
89
+ when org.openhab.core.common.registry.ManagedProvider
90
+ preferred_provider
91
+ else
92
+ raise ArgumentError, "#{preferred_provider.inspect} is not a ManagedProvider"
93
+ end
94
+ end
95
+
96
+ # @abstract
97
+ # @!attribute [r] registry
98
+ #
99
+ # The registry that this provider provides elements for.
100
+ #
101
+ # @return [org.openhab.core.common.registry.Registry]
102
+ #
103
+ def registry
104
+ raise NotImplementedError
105
+ end
106
+
107
+ #
108
+ # Creates a new instance of a provider, registers it, sets it as the
109
+ # default for the thread, calls the block, and then unregisters it.
110
+ #
111
+ # @param [true, false] thread_provider Set this new provider as the default for the thread
112
+ # @yieldparam [Provider] provider The provider
113
+ # @return [Object] The result of the block
114
+ #
115
+ # @!visibility private
116
+ def new(thread_provider: true)
117
+ unless @singleton__instance__.nil? || block_given?
118
+ raise NoMethodError,
119
+ "private method `new' called for #{self}:Class"
120
+ end
121
+
122
+ r = provider = super()
123
+ if block_given?
124
+ if thread_provider
125
+ DSL.provider(provider) do
126
+ r = yield provider
127
+ end
128
+ else
129
+ r = yield provider
130
+ end
131
+ provider.unregister
132
+ end
133
+ r
134
+ end
135
+
136
+ # @!attribute [r] type
137
+ # @!visibility private
138
+ # @return [Symbol]
139
+ #
140
+ def type
141
+ name.split("::")[-2].downcase.to_sym
142
+ end
143
+ end
144
+
145
+ # @!visibility private
146
+ def each(&block)
147
+ @elements.each_value(&block)
148
+ end
149
+
150
+ # @return [String]
151
+ def inspect
152
+ "#<#{self.class.name}:#{object_id}>"
153
+ end
154
+
155
+ # @!visibility private
156
+ def add(element)
157
+ @elements.compute(element.uid) do |_k, old_element|
158
+ raise ArgumentError, "Element #{element.uid} already exists, and cannot be added again" if old_element
159
+
160
+ element
161
+ end
162
+ notify_listeners_about_added_element(element)
163
+ element
164
+ end
165
+
166
+ #
167
+ # Get an element from this provider
168
+ #
169
+ # @param [Object] key The proper key type for the elements in this provider.
170
+ # @return [Object]
171
+ #
172
+ def [](key)
173
+ @elements[key]
174
+ end
175
+ alias_method :get, :[]
176
+
177
+ #
178
+ # Get all elements in this provider
179
+ #
180
+ # @return [Array<Object>]
181
+ #
182
+ def all
183
+ @elements.values
184
+ end
185
+ alias_method :getAll, :all
186
+
187
+ #
188
+ # Remove an element from this provider
189
+ #
190
+ # @return [Object, nil] the removed element
191
+ #
192
+ # @!visibility private
193
+ #
194
+ def remove(key)
195
+ @elements.delete(key)&.tap do |element|
196
+ notify_listeners_about_removed_element(element)
197
+ end
198
+ end
199
+
200
+ # @return [Object, nil] the previous version of the element
201
+ # @!visibility private
202
+ #
203
+ def update(element)
204
+ old = nil
205
+ @elements.compute(element.uid) do |_k, old_element|
206
+ raise ArgumentError, "Element #{element.uid} does not exist to update" unless old_element
207
+
208
+ old = old_element
209
+ element
210
+ end
211
+ notify_listeners_about_updated_element(old, element)
212
+ old
213
+ end
214
+
215
+ # @!visibility private
216
+ def unregister
217
+ self.class.registry.remove_provider(self)
218
+ end
219
+
220
+ private
221
+
222
+ def initialize(unload_priority: nil)
223
+ super()
224
+ @elements = java.util.concurrent.ConcurrentHashMap.new
225
+ self.class.registry.add_provider(self)
226
+ ScriptHandling.script_unloaded(priority: unload_priority) { unregister }
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+ require "weakref"
5
+
6
+ require_relative "script_handling"
7
+
8
+ module OpenHAB
9
+ module Core
10
+ #
11
+ # Contains the infrastructure necessary to listen for events when objects are
12
+ # added/removed from their registry, and keep Proxy objects up-to-date with
13
+ # their underlying object.
14
+ #
15
+ # The including class must meet a few requirements:
16
+ # * Have an `EVENTS` constant that is an Array<String> of the events to
17
+ # listen for
18
+ # * The _last_ entry in the `EVENTS` array must be the "removed" event
19
+ # * It must have a sibling class called `Provider`, with a `.registry`
20
+ # method
21
+ # * It's parent module, downcased and with trailing "s" stripped, must be
22
+ # the method name to retrieve an object from one of the incoming events
23
+ #
24
+ # @!visibility private
25
+ #
26
+ module Proxy
27
+ #
28
+ # Registers and listens to openHAB bus events for objects getting
29
+ # added/updated/removed, and updates references from proxy objects
30
+ # to real objects.
31
+ #
32
+ # Proxies are tracked (via a WeakRef), and their underlying object is
33
+ # if it has changed.
34
+ #
35
+ class EventSubscriber
36
+ include Singleton
37
+ include org.openhab.core.events.EventSubscriber
38
+
39
+ def initialize
40
+ @proxies = java.util.concurrent.ConcurrentHashMap.new
41
+ @parent_module = Object.const_get(self.class.name.split("::")[0..-3].join("::"), false)
42
+ @object_type = @parent_module.name.split("::").last.downcase[0..-2].to_sym
43
+
44
+ @event_types = @parent_module::Proxy::EVENTS
45
+ @uid_method = @parent_module::Proxy::UID_METHOD
46
+ @registry = @parent_module::Provider.registry
47
+ @registration = OSGi.register_service(self, "event.topics": "openhab/*")
48
+ ScriptHandling.script_unloaded { @registration.unregister }
49
+ end
50
+
51
+ #
52
+ # @!attribute [r] subscribed_event_types
53
+ # @return [Set<String>]
54
+ #
55
+ def subscribed_event_types
56
+ @event_types.to_set
57
+ end
58
+
59
+ # @return [org.openhab.core.events.EventFilter, nil]
60
+ def event_filter
61
+ nil
62
+ end
63
+
64
+ #
65
+ # @param [Events::AbstractEvent] event
66
+ # @return [void]
67
+ #
68
+ def receive(event)
69
+ uid = event.__send__(@object_type).__send__(@uid_method)
70
+ object = @registry.get(uid) unless event.class.simple_name == @event_types.last
71
+
72
+ @proxies.compute_if_present(uid) do |_, proxy_ref|
73
+ proxy = resolve_ref(proxy_ref)
74
+ next nil unless proxy
75
+
76
+ proxy.__setobj__(object)
77
+ proxy_ref
78
+ end
79
+ end
80
+
81
+ #
82
+ # Get or create a Proxy for the given raw openHAB object.
83
+ #
84
+ def fetch(object)
85
+ result = nil
86
+
87
+ @proxies.compute(object.__send__(@uid_method)) do |_k, proxy_ref|
88
+ result = resolve_ref(proxy_ref)
89
+ proxy_ref = nil unless result
90
+ result ||= yield
91
+
92
+ proxy_ref || WeakRef.new(result)
93
+ end
94
+
95
+ result
96
+ end
97
+
98
+ private
99
+
100
+ def resolve_ref(proxy_ref)
101
+ proxy_ref.__getobj__ if proxy_ref&.weakref_alive?
102
+ rescue WeakRef::RefError
103
+ nil
104
+ end
105
+ end
106
+
107
+ # @!visibility private
108
+ module ClassMethods
109
+ # Intercepts calls to create new proxies, and returns the already
110
+ # existing (and tracked) proxy if it exists. Otherwise it does create
111
+ # a new instance of Proxy.
112
+ def new(object)
113
+ self::EventSubscriber.instance.fetch(object) { super }
114
+ end
115
+ end
116
+
117
+ # @!visibility private
118
+ def self.included(klass)
119
+ klass.singleton_class.prepend(ClassMethods)
120
+ # define a sub-class of EventSubscriber as a child class of the including class
121
+ klass.const_set(:EventSubscriber, Class.new(EventSubscriber))
122
+ end
123
+
124
+ # @!visibility private
125
+ def to_java
126
+ __getobj__
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ Registry = org.openhab.core.common.registry.AbstractRegistry
6
+
7
+ Registry.field_reader :elementToProvider, :elementReadLock, :identifierToElement, :providerToElements
8
+
9
+ # @abstract
10
+ #
11
+ # The base class for all registries in openHAB.
12
+ #
13
+ class Registry
14
+ #
15
+ # Determines which provider an element is associated with.
16
+ #
17
+ # @param [Object] key
18
+ # @return [org.openhab.core.common.registry.Provider]
19
+ #
20
+ def provider_for(key)
21
+ elementReadLock.lock
22
+ if key.is_a?(org.openhab.core.common.registry.Identifiable)
23
+ element = key
24
+ else
25
+ return nil unless (element = identifierToElement[key])
26
+ end
27
+
28
+ elementToProvider[element]
29
+ ensure
30
+ elementReadLock.unlock
31
+ end
32
+
33
+ # @!attribute [r] providers
34
+ # @return [Enumerable<org.openhab.core.common.registry.Provider>]
35
+ def providers
36
+ providerToElements.keys
37
+ end
38
+ end
39
+ end
40
+ end