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,578 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ #
6
+ # Contains extensions to simplify working with {Item Items}.
7
+ #
8
+ module Items
9
+ # An item builder allows you to dynamically create openHAB items at runtime.
10
+ # This can be useful either to create items as soon as the script loads,
11
+ # or even later based on a rule executing.
12
+ #
13
+ # @example
14
+ # items.build do
15
+ # switch_item MySwitch, "My Switch"
16
+ # switch_item NotAutoupdating, autoupdate: false, channel: "mqtt:topic:1#light"
17
+ # group_item MyGroup do
18
+ # contact_item ItemInGroup, channel: "binding:thing#channel"
19
+ # end
20
+ # # passing `thing` to a group item will automatically use it as the base
21
+ # # for item channels
22
+ # group_item Equipment, tags: Semantics::HVAC, thing: "binding:thing"
23
+ # string_item Mode, tags: Semantics::Control, channel: "mode"
24
+ # end
25
+ # end
26
+ #
27
+ module Builder
28
+ include Core::EntityLookup
29
+
30
+ self.create_dummy_items = true
31
+
32
+ class << self
33
+ private
34
+
35
+ # @!macro def_item_method
36
+ # @!method $1_item(name, label = nil, **kwargs)
37
+ # Create a new $1 item
38
+ # @param name [String, Symbol, Core::Items::Proxy] The name for the new item.
39
+ # Note that you can use a string, a symbol, or even a literal constant name
40
+ # @param label [String] The item label
41
+ # @yieldparam [ItemBuilder] builder Item for further customization
42
+ # @see ItemBuilder#initialize ItemBuilder#initialize for additional arguments.
43
+ def def_item_method(method)
44
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
45
+ def #{method}_item(*args, **kwargs, &block) # def dimmer_item(*args, **kwargs, &block)
46
+ item(#{method.inspect}, *args, **kwargs, &block) # item(:dimmer, *args, **kwargs, &block)
47
+ end # end
48
+ RUBY
49
+ end
50
+ end
51
+
52
+ # @return [ColorItem]
53
+ def_item_method(:color)
54
+ # @return [ContactItem]
55
+ def_item_method(:contact)
56
+ # @return [DateTimeItem]
57
+ def_item_method(:date_time)
58
+ # @return [DimmerItem]
59
+ def_item_method(:dimmer)
60
+ # @return [ImageItem]
61
+ def_item_method(:image)
62
+ # @return [LocationItem]
63
+ def_item_method(:location)
64
+ # @return [NumberItem]
65
+ def_item_method(:number)
66
+ # @return [PlayerItem]
67
+ def_item_method(:player)
68
+ # @return [RollershutterItem]
69
+ def_item_method(:rollershutter)
70
+ # @return [StringItem]
71
+ def_item_method(:string)
72
+ # @return [SwitchItem]
73
+ def_item_method(:switch)
74
+
75
+ # Create a new {GroupItem}
76
+ #
77
+ # @!method group_item(name, label = nil, **kwargs)
78
+ # @param name [String] The name for the new item
79
+ # @param label [String] The item label
80
+ # @param (see GroupItemBuilder#initialize)
81
+ # @yieldparam [GroupItemBuilder] builder Item for further customization
82
+ # @return [GroupItem]
83
+ def group_item(*args, **kwargs, &block)
84
+ item = GroupItemBuilder.new(*args, provider: provider, **kwargs)
85
+ item.instance_eval(&block) if block
86
+ result = provider.add(item)
87
+ item.members.each do |i|
88
+ provider.add(i)
89
+ end
90
+ result
91
+ end
92
+
93
+ include DSL
94
+
95
+ private
96
+
97
+ def item(*args, **kwargs, &block)
98
+ item = ItemBuilder.new(*args, provider: provider, **kwargs)
99
+ item.instance_eval(&block) if block
100
+ r = provider.add(item)
101
+ return Core::Items::Proxy.new(r) if r.is_a?(Item)
102
+
103
+ item
104
+ end
105
+ end
106
+
107
+ # @!visibility private
108
+ class BaseBuilderDSL
109
+ include Builder
110
+
111
+ # @!visibility private
112
+ class ProviderWrapper
113
+ attr_reader :provider
114
+
115
+ def initialize(provider)
116
+ @provider = provider
117
+ end
118
+
119
+ # @!visibility private
120
+ def add(builder)
121
+ item = builder.build
122
+ provider.add(item)
123
+ # make sure to add the item to the registry before linking it
124
+ builder.channels.each do |(channel, config)|
125
+ if !channel.include?(":") &&
126
+ (group = builder.groups.find { |g| g.is_a?(GroupItemBuilder) && g.thing })
127
+ thing = group.thing
128
+ channel = "#{thing}:#{channel}"
129
+ end
130
+ Core::Things::Links::Provider.link(item, channel, config)
131
+ end
132
+ item
133
+ end
134
+ end
135
+ private_constant :ProviderWrapper
136
+
137
+ # @return [org.openhab.core.items.ItemProvider]
138
+ attr_reader :provider
139
+
140
+ def initialize(provider)
141
+ @provider = ProviderWrapper.new(Core::Items::Provider.current(provider))
142
+ end
143
+ end
144
+
145
+ # The ItemBuilder DSL allows you to customize an Item
146
+ class ItemBuilder
147
+ # The type of this item
148
+ # @example
149
+ # type #=> :switch
150
+ # @return [Symbol]
151
+ attr_reader :type
152
+ # Item name
153
+ # @return [String]
154
+ attr_accessor :name
155
+ # Item label
156
+ # @return [String, nil]
157
+ attr_accessor :label
158
+ # Unit dimension (for number items only)
159
+ # @return [String, nil]
160
+ attr_accessor :dimension
161
+ # The formatting pattern for the item's state
162
+ # @return [String, nil]
163
+ attr_accessor :format
164
+ # The icon to be associated with the item
165
+ # @return [Symbol, nil]
166
+ attr_accessor :icon
167
+ # Groups to which this item should be added
168
+ # @return [Array<String, GroupItem>]
169
+ attr_reader :groups
170
+ # Tags to apply to this item
171
+ # @return [Array<String, Semantics::Tag>]
172
+ attr_reader :tags
173
+ # Autoupdate setting
174
+ # @return [true, false, nil]
175
+ attr_accessor :autoupdate
176
+ # {Core::Things::ChannelUID Channel} to link the item to
177
+ # @return [String, Core::Things::ChannelUID, nil]
178
+ attr_accessor :channels
179
+ # @return [Core::Items::Metadata::NamespaceHash]
180
+ attr_reader :metadata
181
+ # Initial state
182
+ # @return [Core::Types::State]
183
+ attr_accessor :state
184
+
185
+ class << self
186
+ # @!visibility private
187
+ def item_factory
188
+ @item_factory ||= org.openhab.core.library.CoreItemFactory.new
189
+ end
190
+
191
+ #
192
+ # Convert the given array to an array of strings.
193
+ # Convert Semantics classes to their simple name.
194
+ #
195
+ # @param [String,Symbol,Semantics::Tag] tags A list of strings, symbols, or Semantics classes
196
+ # @return [Array] An array of strings
197
+ #
198
+ # @example
199
+ # tags = normalize_tags("tag1", Semantics::LivingRoom)
200
+ #
201
+ # @!visibility private
202
+ def normalize_tags(*tags)
203
+ semantics = proc { |tag| tag.respond_to?(:java_class) && tag < Semantics::Tag }
204
+
205
+ tags.compact.map do |tag|
206
+ case tag
207
+ when String then tag
208
+ when Symbol then tag.to_s
209
+ when semantics then tag.java_class.simple_name
210
+ else raise ArgumentError, "`#{tag}` must be a subclass of Semantics::Tag, a `Symbol`, or a `String`."
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ # @param dimension [Symbol, nil] The unit dimension for a {NumberItem} (see {ItemBuilder#dimension})
217
+ # @param format [String, nil] The formatting pattern for the item's state (see {ItemBuilder#format})
218
+ # @param icon [Symbol, nil] The icon to be associated with the item (see {ItemBuilder#icon})
219
+ # @param group [String,
220
+ # GroupItem,
221
+ # GroupItemBuilder,
222
+ # Array<String, GroupItem, GroupItemBuilder>,
223
+ # nil]
224
+ # Group(s) to which this item should be added (see {ItemBuilder#group}).
225
+ # @param groups [String,
226
+ # GroupItem,
227
+ # GroupItemBuilder,
228
+ # Array<String, GroupItem, GroupItemBuilder>,
229
+ # nil]
230
+ # Fluent alias for `group`.
231
+ # @param tag [String, Symbol, Semantics::Tag, Array<String, Symbol, Semantics::Tag>, nil]
232
+ # Tag(s) to apply to this item (see {ItemBuilder#tag}).
233
+ # @param tags [String, Symbol, Semantics::Tag, Array<String, Symbol, Semantics::Tag>, nil]
234
+ # Fluent alias for `tag`.
235
+ # @param autoupdate [true, false, nil] Autoupdate setting (see {ItemBuilder#autoupdate})
236
+ # @param channel [String, Core::Things::ChannelUID, nil] Channel to link the item to
237
+ # @param expire [String] An expiration specification.
238
+ # @param alexa [String, Symbol, Array<(String, Hash<String, Object>)>, nil]
239
+ # Alexa metadata (see {ItemBuilder#alexa})
240
+ # @param ga [String, Symbol, Array<(String, Hash<String, Object>)>, nil]
241
+ # Google Assistant metadata (see {ItemBuilder#ga})
242
+ # @param homekit [String, Symbol, Array<(String, Hash<String, Object>)>, nil]
243
+ # Homekit metadata (see {ItemBuilder#homekit})
244
+ # @param metadata [Hash<String, Hash>] Generic metadata (see {ItemBuilder#metadata})
245
+ # @param state [State] Initial state
246
+ def initialize(type, name = nil, label = nil,
247
+ provider:,
248
+ dimension: nil,
249
+ format: nil,
250
+ icon: nil,
251
+ group: nil,
252
+ groups: nil,
253
+ tag: nil,
254
+ tags: nil,
255
+ autoupdate: nil,
256
+ channel: nil,
257
+ expire: nil,
258
+ alexa: nil,
259
+ ga: nil, # rubocop:disable Naming/MethodParameterName
260
+ homekit: nil,
261
+ metadata: nil,
262
+ state: nil)
263
+ raise ArgumentError, "`name` cannot be nil" if name.nil?
264
+ raise ArgumentError, "`dimension` can only be specified with NumberItem" if dimension && type != :number
265
+
266
+ name = name.name if name.respond_to?(:name)
267
+ if provider.is_a?(GroupItemBuilder)
268
+ name = "#{provider.name_base}#{name}"
269
+ label = "#{provider.label_base}#{label}".strip if label
270
+ end
271
+ @provider = provider
272
+ @type = type
273
+ @name = name.to_s
274
+ @label = label
275
+ @dimension = dimension
276
+ @format = format
277
+ @icon = icon
278
+ @groups = []
279
+ @tags = []
280
+ @metadata = Core::Items::Metadata::NamespaceHash.new
281
+ @metadata.merge!(metadata) if metadata
282
+ @autoupdate = autoupdate
283
+ @channels = []
284
+ @expire = nil
285
+ if expire
286
+ expire = Array(expire)
287
+ expire_config = expire.pop if expire.last.is_a?(Hash)
288
+ expire_config ||= {}
289
+ self.expire(*expire, **expire_config)
290
+ end
291
+ self.alexa(alexa) if alexa
292
+ self.ga(ga) if ga
293
+ self.homekit(homekit) if homekit
294
+ @state = state
295
+
296
+ self.group(*group)
297
+ self.group(*groups)
298
+
299
+ self.tag(*tag)
300
+ self.tag(*tags)
301
+
302
+ self.channel(*channel) if channel
303
+ end
304
+
305
+ #
306
+ # The item's label if one is defined, otherwise its name.
307
+ #
308
+ # @return [String]
309
+ #
310
+ def to_s
311
+ label || name
312
+ end
313
+
314
+ #
315
+ # Tag item
316
+ #
317
+ # @param tags [String, Symbol, Semantics::Tag]
318
+ # @return [void]
319
+ #
320
+ def tag(*tags)
321
+ @tags += self.class.normalize_tags(*tags)
322
+ end
323
+
324
+ #
325
+ # Add this item to a group
326
+ #
327
+ # @param groups [String, GroupItemBuilder, GroupItem]
328
+ # @return [void]
329
+ #
330
+ def group(*groups)
331
+ unless groups.all? do |group|
332
+ group.is_a?(String) || group.is_a?(Core::Items::GroupItem) || group.is_a?(GroupItemBuilder)
333
+ end
334
+ raise ArgumentError, "`group` must be a `GroupItem`, `GroupItemBuilder`, or a `String`"
335
+ end
336
+
337
+ @groups.concat(groups)
338
+ end
339
+
340
+ #
341
+ # @!method alexa(value, config = nil)
342
+ # Shortcut for adding Alexa metadata
343
+ #
344
+ # @see https://www.openhab.org/docs/ecosystem/alexa/
345
+ #
346
+ # @param value [String, Symbol] Type of Alexa endpoint
347
+ # @param config [Hash, nil] Additional Alexa configuration
348
+ # @return [void]
349
+ #
350
+
351
+ #
352
+ # @!method ga(value, config = nil)
353
+ # Shortcut for adding Google Assistant metadata
354
+ #
355
+ # @see https://www.openhab.org/docs/ecosystem/google-assistant/
356
+ #
357
+ # @param value [String, Symbol] Type of Google Assistant endpoint
358
+ # @param config [Hash, nil] Additional Google Assistant configuration
359
+ # @return [void]
360
+ #
361
+
362
+ #
363
+ # @!method homekit(value, config = nil)
364
+ # Shortcut for adding Homekit metadata
365
+ #
366
+ # @see https://www.openhab.org/addons/integrations/homekit/
367
+ #
368
+ # @param value [String, Symbol] Type of Homekit accessory or characteristic
369
+ # @param config [Hash, nil] Additional Homekit configuration
370
+ # @return [void]
371
+ #
372
+
373
+ %i[alexa ga homekit].each do |shortcut|
374
+ define_method(shortcut) do |value = nil, config = nil|
375
+ value, config = value if value.is_a?(Array)
376
+ metadata[shortcut] = [value, config]
377
+ end
378
+ end
379
+
380
+ #
381
+ # Add a channel link to this item.
382
+ #
383
+ # @param config [Hash] Additional configuration, such as profile
384
+ # @return [void]
385
+ #
386
+ # @example
387
+ # items.build do
388
+ # date_time_item Bedroom_Light_Updated do
389
+ # channel "hue:0210:1:bulb1:color", profile: "system:timestamp-update"
390
+ # end
391
+ # end
392
+ #
393
+ def channel(channel, config = {})
394
+ @channels << [channel, config]
395
+ end
396
+
397
+ #
398
+ # @!method expire(command: nil, state: nil)
399
+ #
400
+ # Configure item expiration
401
+ #
402
+ # @return [void]
403
+ #
404
+ # @example Get the current expire setting
405
+ # expire
406
+ # @example Clear any expire setting
407
+ # expire nil
408
+ # @example Use a duration
409
+ # expire 5.hours
410
+ # @example Use a string duration
411
+ # expire "5h"
412
+ # @example Set a specific state on expiration
413
+ # expire 5.minutes, NULL
414
+ # expire 5.minutes, state: NULL
415
+ # @example Send a command on expiration
416
+ # expire 5.minutes, command: OFF
417
+ def expire(*args, command: nil, state: nil)
418
+ unless (0..2).cover?(args.length)
419
+ raise ArgumentError,
420
+ "wrong number of arguments (given #{args.length}, expected 0..2)"
421
+ end
422
+ return @expire if args.empty?
423
+
424
+ state = args.last if args.length == 2
425
+ raise ArgumentError, "cannot provide both command and state" if command && state
426
+
427
+ duration = args.first
428
+ return @expire = nil if duration.nil?
429
+
430
+ duration = duration.to_s[2..].downcase if duration.is_a?(Duration)
431
+ state = "'#{state}'" if state.respond_to?(:to_str) && type == :string
432
+ @expire = duration
433
+ @expire += ",state=#{state}" if state
434
+ @expire += ",command=#{command}" if command
435
+ end
436
+
437
+ # @!visibility private
438
+ def build
439
+ item = create_item
440
+ item.label = label
441
+ item.category = icon.to_s if icon
442
+ groups.each do |group|
443
+ group = group.name if group.respond_to?(:name)
444
+ item.add_group_name(group.to_s)
445
+ end
446
+ tags.each do |tag|
447
+ item.add_tag(tag)
448
+ end
449
+ item.metadata.merge!(metadata)
450
+ item.metadata["autoupdate"] = autoupdate.to_s unless autoupdate.nil?
451
+ item.metadata["expire"] = expire if expire
452
+ item.metadata["stateDescription"] = { "pattern" => format } if format
453
+ item.state = item.format_update(state) unless state.nil?
454
+ item
455
+ end
456
+
457
+ # @return [String]
458
+ def inspect
459
+ s = "#<OpenHAB::Core::Items::#{inspect_type}ItemBuilder#{type_details} #{name} #{label.inspect}"
460
+ s += " category=#{icon.inspect}" if icon
461
+ s += " tags=#{tags.inspect}" unless tags.empty?
462
+ s += " groups=#{groups.map { |g| g.respond_to?(:name) ? g.name : g }.inspect}" unless groups.empty?
463
+ s += " metadata=#{metadata.to_h.inspect}" unless metadata.empty?
464
+ "#{s}>"
465
+ end
466
+
467
+ private
468
+
469
+ # @return [String]
470
+ def inspect_type
471
+ type.to_s.capitalize
472
+ end
473
+
474
+ # @return [String, nil]
475
+ def type_details
476
+ ":#{dimension}" if dimension
477
+ end
478
+
479
+ def create_item
480
+ type = @type.to_s.gsub(/(?:^|_)[a-z]/) { |match| match[-1].upcase }
481
+ type = "#{type}:#{dimension}" if dimension
482
+ self.class.item_factory.create_item(type, name)
483
+ end
484
+ end
485
+
486
+ # Allows customizing a group. You can also call any method from {Builder}, and those
487
+ # items will automatically be a member of this group.
488
+ class GroupItemBuilder < ItemBuilder
489
+ include Builder
490
+
491
+ Builder.public_instance_methods.each do |m|
492
+ next unless Builder.instance_method(m).owner == Builder
493
+
494
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
495
+ def #{m}(*args, groups: nil, **kwargs) # def dimmer_item(*args, groups: nil, **kwargs)
496
+ groups ||= [] # groups ||= []
497
+ groups << self # groups << self
498
+ super # super
499
+ end # end
500
+ RUBY
501
+ end
502
+
503
+ FUNCTION_REGEX = /^([a-z]+)(?:\(([a-z]+)(?:,([a-z]+))*\))?/i.freeze
504
+ private_constant :FUNCTION_REGEX
505
+
506
+ # The combiner function for this group
507
+ # @return [String, nil]
508
+ attr_accessor :function
509
+ # A thing to be used as the base for the channel of any member items
510
+ # @return [Core::Things::ThingUID, Core::Things::Thing, String, nil]
511
+ attr_accessor :thing
512
+ # A prefix to be added to the name of any member items
513
+ # @return [String, nil]
514
+ attr_accessor :name_base
515
+ # A prefix to be added to the label of any member items
516
+ # @return [String, nil]
517
+ attr_accessor :label_base
518
+ # Members to be created in this group
519
+ # @return [Array<ItemBuilder>]
520
+ attr_reader :members
521
+
522
+ # @param type [Symbol, nil] The base type for the group
523
+ # @param function [String, nil] The combiner function for this group
524
+ # @param thing [Core::Things::ThingUID, Core::Things::Thing, String, nil]
525
+ # A Thing to be used as the base for the channel for any contained items.
526
+ # @param (see ItemBuilder#initialize)
527
+ def initialize(*args, type: nil, function: nil, thing: nil, **kwargs)
528
+ raise ArgumentError, "invalid function #{function}" if function && !function.match?(FUNCTION_REGEX)
529
+ raise ArgumentError, "state cannot be set on GroupItems" if kwargs[:state]
530
+
531
+ super(type, *args, **kwargs)
532
+ @function = function
533
+ @members = []
534
+ @thing = thing
535
+ end
536
+
537
+ # @!visibility private
538
+ def create_item
539
+ base_item = super if type
540
+ if function
541
+ match = function.match(FUNCTION_REGEX)
542
+
543
+ dto = org.openhab.core.items.dto.GroupFunctionDTO.new
544
+ dto.name = match[1]
545
+ dto.params = match[2..]
546
+ function = org.openhab.core.items.dto.ItemDTOMapper.map_function(base_item, dto)
547
+ Core::Items::GroupItem.new(name, base_item, function)
548
+ else
549
+ Core::Items::GroupItem.new(name, base_item)
550
+ end
551
+ end
552
+
553
+ # @!visibility private
554
+ def add(child_item)
555
+ @members << child_item
556
+ end
557
+
558
+ private
559
+
560
+ # @return [String]
561
+ def inspect_type
562
+ "Group"
563
+ end
564
+
565
+ # @return [String, nil]
566
+ def type_details
567
+ r = super
568
+ r = "#{r}:#{function}" if function
569
+ r
570
+ end
571
+
572
+ def provider
573
+ self
574
+ end
575
+ end
576
+ end
577
+ end
578
+ end