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,473 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require_relative "generic_item"
6
+ require_relative "group_item"
7
+ require_relative "semantics/enumerable"
8
+
9
+ module OpenHAB
10
+ module Core
11
+ module Items
12
+ # Module for implementing semantics helper methods on {Item} in order to easily navigate
13
+ # the {https://www.openhab.org/docs/tutorial/model.html Semantic Model} in your scripts.
14
+ # This can be extremely useful to find related items in rules that are executed for any member of a group.
15
+ #
16
+ # Wraps {org.openhab.core.model.script.actions.Semantics} as well as adding a few additional convenience methods.
17
+ # Also includes classes for each semantic tag.
18
+ #
19
+ # Be warned that the Semantic model is stricter than can actually be
20
+ # described by tags and groups on an Item. It makes assumptions that any
21
+ # given item only belongs to one semantic type ({Location}, {Equipment}, {Point}).
22
+ #
23
+ # ## Enumerable helper methods
24
+ #
25
+ # {Enumerable Enumerable helper methods} are also provided to complement the semantic model. These methods can be
26
+ # chained together to find specific item(s) based on custom tags or group memberships that are outside
27
+ # the semantic model.
28
+ #
29
+ # The Enumerable helper methods apply to:
30
+ #
31
+ # * {GroupItem#members} and {GroupItem#all_members}. This includes semantic
32
+ # {#location} and {#equipment} because they are also group items.
33
+ # An exception is for Equipments that are an item (not a group)
34
+ # * Array of items, such as the return value of {Enumerable#equipments}, {Enumerable#locations},
35
+ # {Enumerable#points}, {Enumerable#tagged}, {Enumerable#not_tagged}, {Enumerable#member_of},
36
+ # {Enumerable#not_member_of}, {Enumerable#members} methods, etc.
37
+ # * {OpenHAB::DSL.items items[]} hash which contains all items in the system.
38
+ #
39
+ # ## Semantic Classes
40
+ #
41
+ # Each [Semantic
42
+ # Tag](https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.semantics/model/SemanticTags.csv)
43
+ # has a corresponding class within the {org.openhab.core.semantics} class hierarchy.
44
+ # These "semantic classes" are available as constants in the {Semantics} module with the corresponding name.
45
+ # The following table illustrates the semantic constants:
46
+ #
47
+ # | Semantic Constant | openHAB's Semantic Class |
48
+ # | ----------------------- | ------------------------------------------------------ |
49
+ # | `Semantics::LivingRoom` | `org.openhab.core.semantics.model.location.LivingRoom` |
50
+ # | `Semantics::Lightbulb` | `org.openhab.core.semantics.model.equipment.Lightbulb` |
51
+ # | `Semantics::Control` | `org.openhab.core.semantics.model.point.Control` |
52
+ # | `Semantics::Switch` | `org.openhab.core.semantics.model.point.Switch` |
53
+ # | `Semantics::Power` | `org.openhab.core.semantics.model.property.Power` |
54
+ # | ... | ... |
55
+ #
56
+ # These constants can be used as arguments to the {#points},
57
+ # {Enumerable#locations} and {Enumerable#equipments} methods to filter
58
+ # their results. They can also be compared against the return value of
59
+ # {#semantic_type}, {#location_type}, {#equipment_type}, {#point_type},
60
+ # and {#property_type}. They can even be used with
61
+ # {DSL::Items::ItemBuilder#tag}.
62
+ #
63
+ # @see https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.semantics/model/SemanticTags.csv Semantic Tags Table
64
+ #
65
+ # @example Working with tags
66
+ # # Return an array of sibling points with a "Switch" tag
67
+ # Light_Color.points(Semantics::Switch)
68
+ #
69
+ # # check semantic type
70
+ # LoungeRoom_Light.equipment_type == Semantics::Lightbulb
71
+ # Light_Color.property_type == Semantics::Light
72
+ #
73
+ # @example switches.items
74
+ # Group gFullOn
75
+ # Group gRoomOff
76
+ #
77
+ # Group eGarageLights "Garage Lights" (lGarage) [ "Lightbulb" ]
78
+ # Dimmer GarageLights_Dimmer "Garage Lights" <light> (eGarageLights) [ "Switch" ]
79
+ # Number GarageLights_Scene "Scene" (eGarageLights, gFullOn, gRoomOff)
80
+ #
81
+ # Group eMudLights "Mud Room Lights" (lMud) [ "Lightbulb" ]
82
+ # Dimmer MudLights_Dimmer "Garage Lights" <light> (eMudLights) [ "Switch" ]
83
+ # Number MudLights_Scene "Scene" (eMudLights, gFullOn, gRoomOff)
84
+ #
85
+ # @example Find the switch item for a scene channel on a zwave dimmer
86
+ # rule "turn dimmer to full on when switch double-tapped up" do
87
+ # changed gFullOn.members, to: 1.3
88
+ # run do |event|
89
+ # dimmer_item = event.item.points(Semantics::Switch).first
90
+ # dimmer_item.ensure << 100
91
+ # end
92
+ # end
93
+ #
94
+ # @example Turn off all the lights in a room
95
+ # rule "turn off all lights in the room when switch double-tapped down" do
96
+ # changed gRoomOff.members, to: 2.3
97
+ # run do |event|
98
+ # event
99
+ # .item
100
+ # .location
101
+ # .equipments(Semantics::Lightbulb)
102
+ # .members
103
+ # .points(Semantics::Switch)
104
+ # .ensure.off
105
+ # end
106
+ # end
107
+ #
108
+ # @example Finding a related item that doesn't fit in the semantic model
109
+ # # We can use custom tags to identify certain items that don't quite fit in the semantic model.
110
+ # # The extensions to the Enumerable mentioned above can help in this scenario.
111
+ #
112
+ # # In the following example, the TV `Equipment` has three `Points`. However, we are using custom tags
113
+ # # `Application` and `Channel` to identify the corresponding points, since the semantic model
114
+ # # doesn't have a specific property for them.
115
+ #
116
+ # # Here, we use Enumerable#tagged
117
+ # # to find the point with the custom tag that we want.
118
+ #
119
+ # # Item model:
120
+ # Group gTVPower
121
+ # Group lLivingRoom [ "LivingRoom" ]
122
+ #
123
+ # Group eTV "TV" (lLivingRoom) [ "Television" ]
124
+ # Switch TV_Power "Power" (eTV, gTVPower) [ "Switch", "Power" ]
125
+ # String TV_Application "App" (eTV) [ "Control", "Application" ]
126
+ # String TV_Channel "Channel" (eTV) [ "Control", "Channel" ]
127
+ #
128
+ # # Rule:
129
+ # rule 'Switch TV to Netflix on startup' do
130
+ # changed gTVPower.members, to: ON
131
+ # run do |event|
132
+ # application = event.item.points.tagged('Application').first
133
+ # application << 'netflix'
134
+ # end
135
+ # end
136
+ #
137
+ # @example Find all semantic entities regardless of hierarchy
138
+ # # All locations
139
+ # items.locations
140
+ #
141
+ # # All rooms
142
+ # items.locations(Semantics::Room)
143
+ #
144
+ # # All equipments
145
+ # items.equipments
146
+ #
147
+ # # All lightbulbs
148
+ # items.equipments(Semantics::Lightbulb)
149
+ #
150
+ # # All blinds
151
+ # items.equipments(Semantics::Blinds)
152
+ #
153
+ # # Turn off all "Power control"
154
+ # items.points(Semantics::Control, Semantics::Power).off
155
+ #
156
+ # # All items tagged "SmartLightControl"
157
+ # items.tagged("SmartLightControl")
158
+ #
159
+ #
160
+ module Semantics
161
+ GenericItem.include(self)
162
+ GroupItem.extend(Forwardable)
163
+ GroupItem.def_delegators :members, :equipments, :locations
164
+
165
+ # @!parse
166
+ # class Items::GroupItem
167
+ # #
168
+ # # @!attribute [r] equipments
169
+ # #
170
+ # # Calls {Enumerable#equipments members.equipments}.
171
+ # #
172
+ # # @return (see Enumerable#equipments)
173
+ # #
174
+ # # @see Enumerable#equipments
175
+ # #
176
+ # def equipments; end
177
+ #
178
+ # #
179
+ # # @!attribute [r] locations
180
+ # #
181
+ # # Calls {Enumerable#locations members.locations}.
182
+ # #
183
+ # # @return (see Enumerable#locations)
184
+ # #
185
+ # # @see Enumerable#locations
186
+ # #
187
+ # def locations; end
188
+ # end
189
+ #
190
+
191
+ # import all the semantics constants
192
+ [org.openhab.core.semantics.model.point.Points,
193
+ org.openhab.core.semantics.model.property.Properties,
194
+ org.openhab.core.semantics.model.equipment.Equipments,
195
+ org.openhab.core.semantics.model.location.Locations].each do |parent_tag|
196
+ parent_tag.stream.for_each do |tag|
197
+ const_set(tag.simple_name.to_sym, tag.ruby_class)
198
+ end
199
+ end
200
+ # This is a marker interface for all semantic tag classes.
201
+ # @interface
202
+ Tag = org.openhab.core.semantics.Tag
203
+
204
+ # @!parse
205
+ # # This is the super interface for all types that represent a Location.
206
+ # # @interface
207
+ # Location = org.openhab.core.semantics.Location
208
+ #
209
+ # # This is the super interface for all types that represent an Equipment.
210
+ # # @interface
211
+ # Equipment = org.openhab.core.semantics.Equipment
212
+ #
213
+ # # This is the super interface for all types that represent a Point.
214
+ # # @interface
215
+ # Point = org.openhab.core.semantics.Point
216
+ #
217
+ # # This is the super interface for all property tags.
218
+ # # @interface
219
+ # Property = org.openhab.core.semantics.Property
220
+
221
+ # put ourself into the global namespace, replacing the action
222
+ Object.send(:remove_const, :Semantics)
223
+ ::Semantics = self # rubocop:disable Naming/ConstantName
224
+
225
+ #
226
+ # Checks if this Item is a {Location}
227
+ #
228
+ # This is implemented as checking if the item's {#semantic_type}
229
+ # is a {Location}. I.e. an Item has a single {#semantic_type}.
230
+ #
231
+ # @return [true, false]
232
+ #
233
+ def location?
234
+ Actions::Semantics.location?(self)
235
+ end
236
+
237
+ #
238
+ # Checks if this Item is an {Equipment}
239
+ #
240
+ # This is implemented as checking if the item's {#semantic_type}
241
+ # is an {Equipment}. I.e. an Item has a single {#semantic_type}.
242
+ #
243
+ # @return [true, false]
244
+ #
245
+ def equipment?
246
+ Actions::Semantics.equipment?(self)
247
+ end
248
+
249
+ # Checks if this Item is a {Point}
250
+ #
251
+ # This is implemented as checking if the item's {#semantic_type}
252
+ # is a {Point}. I.e. an Item has a single {#semantic_type}.
253
+ #
254
+ # @return [true, false]
255
+ #
256
+ def point?
257
+ Actions::Semantics.point?(self)
258
+ end
259
+
260
+ #
261
+ # Checks if this Item has any semantic tags
262
+ #
263
+ # @return [true, false]
264
+ #
265
+ def semantic?
266
+ !!semantic_type
267
+ end
268
+
269
+ #
270
+ # @!attribute [r] location
271
+ #
272
+ # Gets the related {Location} Item of this Item.
273
+ #
274
+ # Checks ancestor groups one level at a time, returning the first
275
+ # {Location} Item found.
276
+ #
277
+ # @return [Item, nil]
278
+ #
279
+ def location
280
+ Actions::Semantics.get_location(self)&.then(&Proxy.method(:new))
281
+ end
282
+
283
+ #
284
+ # @!attribute [r] location_type
285
+ #
286
+ # Returns the sub-class of {Location} related to this Item.
287
+ #
288
+ # In other words, the {#semantic_type} of this Item's {Location}.
289
+ #
290
+ # @return [Class, nil]
291
+ #
292
+ def location_type
293
+ Actions::Semantics.get_location_type(self)&.ruby_class
294
+ end
295
+
296
+ #
297
+ # @!attribute [r] equipment
298
+ #
299
+ # Gets the related {Equipment} Item of this Item.
300
+ #
301
+ # Checks ancestor groups one level at a time, returning the first {Equipment} Item found.
302
+ #
303
+ # @return [Item, nil]
304
+ #
305
+ def equipment
306
+ Actions::Semantics.get_equipment(self)&.then(&Proxy.method(:new))
307
+ end
308
+
309
+ #
310
+ # @!attribute [r] equipment_type
311
+ #
312
+ # Returns the sub-class of {Equipment} related to this Item.
313
+ #
314
+ # In other words, the {#semantic_type} of this Item's {Equipment}.
315
+ #
316
+ # @return [Class, nil]
317
+ #
318
+ def equipment_type
319
+ Actions::Semantics.get_equipment_type(self)&.ruby_class
320
+ end
321
+
322
+ #
323
+ # @!attribute [r] point_type
324
+ #
325
+ # Returns the sub-class of {Point} this Item is tagged with.
326
+ #
327
+ # @return [Class, nil]
328
+ #
329
+ def point_type
330
+ Actions::Semantics.get_point_type(self)&.ruby_class
331
+ end
332
+
333
+ #
334
+ # @!attribute [r] property_type
335
+ #
336
+ # Returns the sub-class of {Property} this Item is tagged with.
337
+ #
338
+ # @return [Class, nil]
339
+ #
340
+ def property_type
341
+ Actions::Semantics.get_property_type(self)&.ruby_class
342
+ end
343
+
344
+ # @!attribute [r] semantic_type
345
+ #
346
+ # Returns the sub-class of {Tag} this Item is tagged with.
347
+ #
348
+ # It will only return the first applicable Tag, preferring
349
+ # a sub-class of {Location}, {Equipment}, or {Point} first,
350
+ # and if none of those are found, looks for a {Property}.
351
+ #
352
+ # @return [Class, nil]
353
+ #
354
+ def semantic_type
355
+ Actions::Semantics.get_semantic_type(self)&.ruby_class
356
+ end
357
+
358
+ #
359
+ # Return the related Point Items.
360
+ #
361
+ # Searches this Equipment Item for Points that are tagged appropriately.
362
+ #
363
+ # If called on a Point Item, it will automatically search for sibling Points
364
+ # (and remove itself if found).
365
+ #
366
+ # @example Get all points for a TV
367
+ # eGreatTV.points
368
+ # @example Search an Equipment item for its switch
369
+ # eGuestFan.points(Semantics::Switch) # => [GuestFan_Dimmer]
370
+ # @example Search a Thermostat item for its current temperature item
371
+ # eFamilyThermostat.points(Semantics::Status, Semantics::Temperature)
372
+ # # => [FamilyThermostat_AmbTemp]
373
+ # @example Search a Thermostat item for is setpoints
374
+ # eFamilyThermostat.points(Semantics::Control, Semantics::Temperature)
375
+ # # => [FamilyThermostat_HeatingSetpoint, FamilyThermostat_CoolingSetpoint]
376
+ # @example Given a A/V receiver's input item, search for its power item
377
+ # FamilyReceiver_Input.points(Semantics::Switch) # => [FamilyReceiver_Switch]
378
+ #
379
+ # @param [Class] point_or_property_types
380
+ # Pass 1 or 2 classes that are sub-classes of {Point} or {Property}.
381
+ # Note that when comparing against semantic tags, it does a sub-class check.
382
+ # So if you search for [Control], you'll get items tagged with [Switch].
383
+ # @return [Array<Item>]
384
+ #
385
+ def points(*point_or_property_types)
386
+ return members.points(*point_or_property_types) if equipment? || location?
387
+
388
+ # automatically search the parent equipment (or location?!) for sibling points
389
+ result = (equipment || location)&.points(*point_or_property_types) || []
390
+ result.delete(self)
391
+ result
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ # @!parse Semantics = OpenHAB::Core::Items::Semantics
399
+
400
+ # Additions to Enumerable to allow easily filtering groups of items based on the semantic model
401
+ module Enumerable
402
+ #
403
+ # @!group Filtering Methods
404
+ #
405
+
406
+ # Returns a new array of items that are a semantics Location (optionally of the given type)
407
+ # @return [Array<Item>]
408
+ def locations(type = nil)
409
+ if type && (!type.is_a?(Module) || !(type < Semantics::Location))
410
+ raise ArgumentError, "type must be a subclass of Location"
411
+ end
412
+
413
+ result = select(&:location?)
414
+ result.select! { |i| i.location_type <= type } if type
415
+
416
+ result
417
+ end
418
+
419
+ # Returns a new array of items that are a semantics equipment (optionally of the given type)
420
+ #
421
+ # @note As {Semantics::Equipment equipments} are usually
422
+ # {GroupItem GroupItems}, this method therefore returns an array of
423
+ # {GroupItem GroupItems}. In order to get the {Semantics::Point points}
424
+ # that belong to the {Semantics::Equipment equipments}, use {#members}
425
+ # before calling {#points}. See the example with {#points}.
426
+ #
427
+ # @return [Array<Item>]
428
+ #
429
+ # @example Get all TVs in a room
430
+ # lGreatRoom.equipments(Semantics::Screen)
431
+ def equipments(type = nil)
432
+ if type && (!type.is_a?(Module) || !(type < Semantics::Equipment))
433
+ raise ArgumentError, "type must be a subclass of Equipment"
434
+ end
435
+
436
+ result = select(&:equipment?)
437
+ result.select! { |i| i.equipment_type <= type } if type
438
+
439
+ result
440
+ end
441
+
442
+ # Returns a new array of items that are semantics points (optionally of a given type)
443
+ #
444
+ # @return [Array<Item>]
445
+ #
446
+ # @example Get all the power switch items for every equipment in a room
447
+ # lGreatRoom.equipments.members.points(Semantics::Switch)
448
+ #
449
+ # @see #members
450
+ #
451
+ def points(*point_or_property_types)
452
+ unless (0..2).cover?(point_or_property_types.length)
453
+ raise ArgumentError, "wrong number of arguments (given #{point_or_property_types.length}, expected 0..2)"
454
+ end
455
+ unless point_or_property_types.all? do |tag|
456
+ tag.is_a?(Module) &&
457
+ (tag < Semantics::Point || tag < Semantics::Property)
458
+ end
459
+ raise ArgumentError, "point_or_property_types must all be a subclass of Point or Property"
460
+ end
461
+ if point_or_property_types.count { |tag| tag < Semantics::Point } > 1 ||
462
+ point_or_property_types.count { |tag| tag < Semantics::Property } > 1
463
+ raise ArgumentError, "point_or_property_types cannot both be a subclass of Point or Property"
464
+ end
465
+
466
+ select do |point|
467
+ point.point? && point_or_property_types.all? do |tag|
468
+ (tag < Semantics::Point && point.point_type <= tag) ||
469
+ (tag < Semantics::Property && point.property_type&.<=(tag))
470
+ end
471
+ end
472
+ end
473
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Items
8
+ #
9
+ # Delegates state storage to a Hash providing methods to operate with states
10
+ #
11
+ class StateStorage < SimpleDelegator
12
+ #
13
+ # Create a StateStorage object that stores the states of the given items
14
+ #
15
+ # @param [Item] items A list of items
16
+ #
17
+ # @return [StateStorage] A state storage object
18
+ #
19
+ # @!visibility private
20
+ def self.from_items(*items)
21
+ StateStorage.new($events.store_states(*items.map(&:to_java)).to_h)
22
+ end
23
+
24
+ #
25
+ # Restore the stored states of all items
26
+ #
27
+ # @return [void]
28
+ #
29
+ def restore
30
+ $events.restore_states(to_h)
31
+ end
32
+
33
+ #
34
+ # Restore states for items that have changed
35
+ #
36
+ # @return [void]
37
+ #
38
+ def restore_changes
39
+ $events.restore_states(select { |item, value| item.state != value })
40
+ end
41
+
42
+ #
43
+ # Detect if any items have changed states since being stored
44
+ #
45
+ # @return [true,false] True if any items have changed states, false otherwise
46
+ #
47
+ def changed?
48
+ any? { |item, value| item.state != value }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "generic_item"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Items
8
+ java_import org.openhab.core.library.items.StringItem
9
+
10
+ #
11
+ # A {StringItem} can be used for any kind of string to either send or
12
+ # receive from a device.
13
+ #
14
+ # @!attribute [r] state
15
+ # @return [StringType, nil]
16
+ #
17
+ # @example
18
+ # # StringOne has a current state of "Hello"
19
+ # StringOne << StringOne + " World!"
20
+ # # StringOne will eventually have a state of 'Hello World!'
21
+ #
22
+ class StringItem < GenericItem
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ # @!parse StringItem = OpenHAB::Core::Items::StringItem
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "generic_item"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Items
8
+ java_import org.openhab.core.library.items.SwitchItem
9
+
10
+ #
11
+ # A SwitchItem represents a normal switch that can be ON or OFF.
12
+ # Useful for normal lights, presence detection etc.
13
+ #
14
+ # @!attribute [r] state
15
+ # @return [OnOffType, nil]
16
+ #
17
+ #
18
+ # @example Turn on all switches in a `Group:Switch` called Switches
19
+ # Switches.on
20
+ #
21
+ # @example Turn on all switches in a group called Switches that are off
22
+ # Switches.select(&:off?).each(&:on)
23
+ #
24
+ # @example Switches accept booelan commands (true/false)
25
+ # # Turn on switch
26
+ # SwitchItem << true
27
+ #
28
+ # # Turn off switch
29
+ # SwitchItem << false
30
+ #
31
+ # # Turn off switch if any in another group is on
32
+ # SwitchItem << Switches.any?(&:on?)
33
+ #
34
+ # @example Invert all Switches
35
+ # items.grep(SwitchItem)
36
+ # .each(&:toggle)
37
+ #
38
+ class SwitchItem < GenericItem
39
+ # Convert boolean commands to ON/OFF
40
+ # @!visibility private
41
+ def format_type(command)
42
+ return Types::OnOffType.from(command) if [true, false].include?(command)
43
+
44
+ super
45
+ end
46
+
47
+ #
48
+ # Send a command to invert the state of the switch
49
+ #
50
+ # @return [self]
51
+ #
52
+ def toggle
53
+ return on unless state?
54
+
55
+ command(!state)
56
+ end
57
+
58
+ # @!method on?
59
+ # Check if the item state == {ON}
60
+ # @return [true,false]
61
+
62
+ # @!method off?
63
+ # Check if the item state == {OFF}
64
+ # @return [true,false]
65
+
66
+ # @!method on
67
+ # Send the {ON} command to the item
68
+ # @return [SwitchItem] `self`
69
+
70
+ # @!method off
71
+ # Send the {OFF} command to the item
72
+ # @return [SwitchItem] `self`
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # @!parse SwitchItem = OpenHAB::Core::Items::SwitchItem