openhab-jrubyscripting 5.0.0.rc1

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 (164) hide show
  1. checksums.yaml +7 -0
  2. data/lib/openhab/core/actions.rb +163 -0
  3. data/lib/openhab/core/entity_lookup.rb +144 -0
  4. data/lib/openhab/core/events/abstract_event.rb +17 -0
  5. data/lib/openhab/core/events/item_channel_link.rb +36 -0
  6. data/lib/openhab/core/events/item_command_event.rb +78 -0
  7. data/lib/openhab/core/events/item_event.rb +22 -0
  8. data/lib/openhab/core/events/item_state_changed_event.rb +52 -0
  9. data/lib/openhab/core/events/item_state_event.rb +51 -0
  10. data/lib/openhab/core/events/thing.rb +29 -0
  11. data/lib/openhab/core/events/thing_status_info_event.rb +53 -0
  12. data/lib/openhab/core/events.rb +10 -0
  13. data/lib/openhab/core/items/accepted_data_types.rb +29 -0
  14. data/lib/openhab/core/items/color_item.rb +52 -0
  15. data/lib/openhab/core/items/contact_item.rb +52 -0
  16. data/lib/openhab/core/items/date_time_item.rb +58 -0
  17. data/lib/openhab/core/items/dimmer_item.rb +148 -0
  18. data/lib/openhab/core/items/generic_item.rb +344 -0
  19. data/lib/openhab/core/items/group_item.rb +174 -0
  20. data/lib/openhab/core/items/image_item.rb +109 -0
  21. data/lib/openhab/core/items/location_item.rb +34 -0
  22. data/lib/openhab/core/items/metadata/hash.rb +390 -0
  23. data/lib/openhab/core/items/metadata/namespace_hash.rb +469 -0
  24. data/lib/openhab/core/items/metadata.rb +11 -0
  25. data/lib/openhab/core/items/number_item.rb +62 -0
  26. data/lib/openhab/core/items/numeric_item.rb +22 -0
  27. data/lib/openhab/core/items/persistence.rb +327 -0
  28. data/lib/openhab/core/items/player_item.rb +66 -0
  29. data/lib/openhab/core/items/proxy.rb +59 -0
  30. data/lib/openhab/core/items/registry.rb +66 -0
  31. data/lib/openhab/core/items/rollershutter_item.rb +68 -0
  32. data/lib/openhab/core/items/semantics/enumerable.rb +152 -0
  33. data/lib/openhab/core/items/semantics.rb +476 -0
  34. data/lib/openhab/core/items/state_storage.rb +53 -0
  35. data/lib/openhab/core/items/string_item.rb +28 -0
  36. data/lib/openhab/core/items/switch_item.rb +78 -0
  37. data/lib/openhab/core/items.rb +114 -0
  38. data/lib/openhab/core/lazy_array.rb +52 -0
  39. data/lib/openhab/core/profile_factory.rb +118 -0
  40. data/lib/openhab/core/script_handling.rb +55 -0
  41. data/lib/openhab/core/things/channel.rb +48 -0
  42. data/lib/openhab/core/things/channel_uid.rb +51 -0
  43. data/lib/openhab/core/things/item_channel_link.rb +33 -0
  44. data/lib/openhab/core/things/profile_callback.rb +52 -0
  45. data/lib/openhab/core/things/proxy.rb +69 -0
  46. data/lib/openhab/core/things/registry.rb +46 -0
  47. data/lib/openhab/core/things/thing.rb +194 -0
  48. data/lib/openhab/core/things.rb +22 -0
  49. data/lib/openhab/core/timer.rb +128 -0
  50. data/lib/openhab/core/types/comparable_type.rb +23 -0
  51. data/lib/openhab/core/types/date_time_type.rb +259 -0
  52. data/lib/openhab/core/types/decimal_type.rb +192 -0
  53. data/lib/openhab/core/types/hsb_type.rb +183 -0
  54. data/lib/openhab/core/types/increase_decrease_type.rb +34 -0
  55. data/lib/openhab/core/types/next_previous_type.rb +34 -0
  56. data/lib/openhab/core/types/numeric_type.rb +52 -0
  57. data/lib/openhab/core/types/on_off_type.rb +46 -0
  58. data/lib/openhab/core/types/open_closed_type.rb +41 -0
  59. data/lib/openhab/core/types/percent_type.rb +95 -0
  60. data/lib/openhab/core/types/play_pause_type.rb +38 -0
  61. data/lib/openhab/core/types/point_type.rb +117 -0
  62. data/lib/openhab/core/types/quantity_type.rb +327 -0
  63. data/lib/openhab/core/types/raw_type.rb +26 -0
  64. data/lib/openhab/core/types/refresh_type.rb +27 -0
  65. data/lib/openhab/core/types/rewind_fastforward_type.rb +38 -0
  66. data/lib/openhab/core/types/stop_move_type.rb +34 -0
  67. data/lib/openhab/core/types/string_type.rb +76 -0
  68. data/lib/openhab/core/types/type.rb +117 -0
  69. data/lib/openhab/core/types/un_def_type.rb +38 -0
  70. data/lib/openhab/core/types/up_down_type.rb +50 -0
  71. data/lib/openhab/core/types.rb +69 -0
  72. data/lib/openhab/core/uid.rb +36 -0
  73. data/lib/openhab/core.rb +85 -0
  74. data/lib/openhab/core_ext/java/duration.rb +115 -0
  75. data/lib/openhab/core_ext/java/local_date.rb +93 -0
  76. data/lib/openhab/core_ext/java/local_time.rb +106 -0
  77. data/lib/openhab/core_ext/java/month.rb +59 -0
  78. data/lib/openhab/core_ext/java/month_day.rb +105 -0
  79. data/lib/openhab/core_ext/java/period.rb +103 -0
  80. data/lib/openhab/core_ext/java/temporal_amount.rb +34 -0
  81. data/lib/openhab/core_ext/java/time.rb +58 -0
  82. data/lib/openhab/core_ext/java/unit.rb +15 -0
  83. data/lib/openhab/core_ext/java/zoned_date_time.rb +116 -0
  84. data/lib/openhab/core_ext/ruby/array.rb +21 -0
  85. data/lib/openhab/core_ext/ruby/class.rb +15 -0
  86. data/lib/openhab/core_ext/ruby/date.rb +89 -0
  87. data/lib/openhab/core_ext/ruby/numeric.rb +190 -0
  88. data/lib/openhab/core_ext/ruby/range.rb +70 -0
  89. data/lib/openhab/core_ext/ruby/time.rb +104 -0
  90. data/lib/openhab/core_ext.rb +18 -0
  91. data/lib/openhab/dsl/events/watch_event.rb +18 -0
  92. data/lib/openhab/dsl/events.rb +9 -0
  93. data/lib/openhab/dsl/gems.rb +3 -0
  94. data/lib/openhab/dsl/items/builder.rb +618 -0
  95. data/lib/openhab/dsl/items/ensure.rb +93 -0
  96. data/lib/openhab/dsl/items/timed_command.rb +236 -0
  97. data/lib/openhab/dsl/rules/automation_rule.rb +308 -0
  98. data/lib/openhab/dsl/rules/builder.rb +1373 -0
  99. data/lib/openhab/dsl/rules/guard.rb +115 -0
  100. data/lib/openhab/dsl/rules/name_inference.rb +160 -0
  101. data/lib/openhab/dsl/rules/property.rb +76 -0
  102. data/lib/openhab/dsl/rules/rule_triggers.rb +96 -0
  103. data/lib/openhab/dsl/rules/terse.rb +63 -0
  104. data/lib/openhab/dsl/rules/triggers/changed.rb +169 -0
  105. data/lib/openhab/dsl/rules/triggers/channel.rb +57 -0
  106. data/lib/openhab/dsl/rules/triggers/command.rb +107 -0
  107. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +161 -0
  108. data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +164 -0
  109. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +195 -0
  110. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +127 -0
  111. data/lib/openhab/dsl/rules/triggers/trigger.rb +56 -0
  112. data/lib/openhab/dsl/rules/triggers/updated.rb +130 -0
  113. data/lib/openhab/dsl/rules/triggers/watch/watch.rb +55 -0
  114. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +155 -0
  115. data/lib/openhab/dsl/rules/triggers.rb +12 -0
  116. data/lib/openhab/dsl/rules.rb +29 -0
  117. data/lib/openhab/dsl/script_handling.rb +55 -0
  118. data/lib/openhab/dsl/things/builder.rb +263 -0
  119. data/lib/openhab/dsl/thread_local.rb +48 -0
  120. data/lib/openhab/dsl/timer_manager.rb +191 -0
  121. data/lib/openhab/dsl/version.rb +9 -0
  122. data/lib/openhab/dsl.rb +686 -0
  123. data/lib/openhab/log.rb +348 -0
  124. data/lib/openhab/osgi.rb +70 -0
  125. data/lib/openhab/rspec/configuration.rb +56 -0
  126. data/lib/openhab/rspec/example_group.rb +90 -0
  127. data/lib/openhab/rspec/helpers.rb +439 -0
  128. data/lib/openhab/rspec/hooks.rb +93 -0
  129. data/lib/openhab/rspec/jruby.rb +46 -0
  130. data/lib/openhab/rspec/karaf.rb +811 -0
  131. data/lib/openhab/rspec/mocks/bundle_install_support.rb +25 -0
  132. data/lib/openhab/rspec/mocks/bundle_resolver.rb +30 -0
  133. data/lib/openhab/rspec/mocks/event_admin.rb +146 -0
  134. data/lib/openhab/rspec/mocks/metadata_provider.rb +75 -0
  135. data/lib/openhab/rspec/mocks/persistence_service.rb +140 -0
  136. data/lib/openhab/rspec/mocks/safe_caller.rb +40 -0
  137. data/lib/openhab/rspec/mocks/synchronous_executor.rb +56 -0
  138. data/lib/openhab/rspec/mocks/thing_handler.rb +76 -0
  139. data/lib/openhab/rspec/mocks/timer.rb +95 -0
  140. data/lib/openhab/rspec/openhab/core/actions.rb +26 -0
  141. data/lib/openhab/rspec/openhab/core/items/proxy.rb +27 -0
  142. data/lib/openhab/rspec/openhab/core/things/proxy.rb +27 -0
  143. data/lib/openhab/rspec/shell.rb +31 -0
  144. data/lib/openhab/rspec/suspend_rules.rb +60 -0
  145. data/lib/openhab/rspec.rb +17 -0
  146. data/lib/openhab/yard/cli/stats.rb +23 -0
  147. data/lib/openhab/yard/code_objects/group_object.rb +17 -0
  148. data/lib/openhab/yard/code_objects/java/base.rb +31 -0
  149. data/lib/openhab/yard/code_objects/java/class_object.rb +11 -0
  150. data/lib/openhab/yard/code_objects/java/field_object.rb +15 -0
  151. data/lib/openhab/yard/code_objects/java/interface_object.rb +15 -0
  152. data/lib/openhab/yard/code_objects/java/package_object.rb +11 -0
  153. data/lib/openhab/yard/code_objects/java/proxy.rb +23 -0
  154. data/lib/openhab/yard/handlers/jruby/base.rb +49 -0
  155. data/lib/openhab/yard/handlers/jruby/class_handler.rb +18 -0
  156. data/lib/openhab/yard/handlers/jruby/constant_handler.rb +18 -0
  157. data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +27 -0
  158. data/lib/openhab/yard/handlers/jruby/mixin_handler.rb +23 -0
  159. data/lib/openhab/yard/html_helper.rb +44 -0
  160. data/lib/openhab/yard/tags/constant_directive.rb +20 -0
  161. data/lib/openhab/yard/tags/group_directive.rb +24 -0
  162. data/lib/openhab/yard/tags/library.rb +3 -0
  163. data/lib/openhab/yard.rb +32 -0
  164. metadata +504 -0
@@ -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
@@ -0,0 +1,114 @@
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
+ end
29
+
30
+ private
31
+
32
+ # takes an array of Type java classes and returns
33
+ # all the Enum values, in a flat array
34
+ def values_for_enums(enums)
35
+ enums.map(&:ruby_class)
36
+ .select { |k| k < java.lang.Enum }
37
+ .flat_map(&:values)
38
+ end
39
+
40
+ # define predicates for checking if an item is in one of the Enum states
41
+ def def_predicate_methods(klass)
42
+ values_for_enums(klass.ACCEPTED_DATA_TYPES).each do |state|
43
+ _command_predicate, state_predicate = Types::PREDICATE_ALIASES[state.to_s]
44
+ next if klass.instance_methods.include?(state_predicate)
45
+
46
+ logger.trace("Defining #{klass}##{state_predicate} for #{state}")
47
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
48
+ def #{state_predicate} # def on?
49
+ raw_state == #{state} # raw_state == ON
50
+ end # end
51
+ RUBY
52
+ end
53
+ end
54
+
55
+ # define methods for commanding an item to one of the Enum states
56
+ # as well as predicates for if an ItemCommandEvent is one of those commands
57
+ def def_command_methods(klass)
58
+ values_for_enums(klass.ACCEPTED_COMMAND_TYPES).each do |value|
59
+ command = Types::COMMAND_ALIASES[value.to_s]
60
+ next if klass.instance_methods.include?(command)
61
+
62
+ logger.trace("Defining #{klass}##{command} for #{value}")
63
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
64
+ def #{command}(for: nil, on_expire: nil, &block) # def on(for: nil, on_expire: nil, &block )
65
+ command(#{value}, for: binding.local_variable_get(:for), on_expire: on_expire, &block) # command(ON, for: nil, expire: nil, &block)
66
+ end # end
67
+ RUBY
68
+
69
+ logger.trace("Defining Enumerable##{command} for #{value}")
70
+ Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
71
+ def #{command} # def on
72
+ each(&:#{command}) # each(&:on)
73
+ end # end
74
+ RUBY
75
+
76
+ # Override the inherited methods from Enumerable and send it to the base_item
77
+ GroupItem.class_eval <<~RUBY, __FILE__, __LINE__ + 1
78
+ def #{command} # def on
79
+ method_missing(:#{command}) # method_missing(:on)
80
+ end # end
81
+ RUBY
82
+
83
+ logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
84
+ Events::ItemCommandEvent.class_eval <<~RUBY, __FILE__, __LINE__ + 1
85
+ def #{command}? # def refresh?
86
+ command == #{value} # command == REFRESH
87
+ end # end
88
+ RUBY
89
+ end
90
+ end
91
+
92
+ def concrete_item_classes
93
+ constants.map { |c| const_get(c) }
94
+ .grep(Module)
95
+ .select { |k| k < GenericItem }
96
+ end
97
+ end
98
+
99
+ # sort classes by hierarchy so we define methods on parent classes first
100
+ constants.map { |c| const_get(c) }
101
+ .grep(Module)
102
+ .select { |k| k <= GenericItem && k != GroupItem && k != StringItem }
103
+ .sort { |a, b| a < b ? 1 : -1 }
104
+ .each do |klass|
105
+ klass.field_reader :ACCEPTED_COMMAND_TYPES, :ACCEPTED_DATA_TYPES unless klass == GenericItem
106
+
107
+ def_predicate_methods(klass)
108
+ def_command_methods(klass)
109
+ end
110
+
111
+ prepend_accepted_data_types
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ # Common base class for array-like collections that have lookup
6
+ # methods to avoid instantiating the elements if you only use
7
+ # the lookup method
8
+ #
9
+ # your class should implement to_a
10
+ #
11
+ module LazyArray
12
+ include Enumerable
13
+
14
+ # @!visibility private
15
+ def self.included(klass)
16
+ klass.undef_method :inspect
17
+ klass.undef_method :to_s
18
+ end
19
+
20
+ # Calls the given block once for each object, passing that object as a
21
+ # parameter. Returns self.
22
+ #
23
+ # If no block is given, an Enumerator is returned.
24
+ def each(&block)
25
+ to_a.each(&block)
26
+ self
27
+ end
28
+
29
+ # Implicitly convertible to array
30
+ #
31
+ # @return [Array]
32
+ #
33
+ def to_ary
34
+ to_a
35
+ end
36
+
37
+ # Delegate any other methods to the actual array, exclude mutating methods
38
+ def method_missing(method, *args, &block)
39
+ return to_a.send(method, *args, &block) if method[-1] != "!" && Array.instance_methods.include?(method)
40
+
41
+ super
42
+ end
43
+
44
+ # @!visibility private
45
+ def respond_to_missing?(method, include_private = false)
46
+ return true if method[-1] != "!" && Array.instance_methods.include?(method.to_sym)
47
+
48
+ super
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,118 @@
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[:config] = @context.configuration
73
+ params[:link] = @callback.link
74
+ params[:item] = @callback.link.item
75
+ params[:channel_uid] = @callback.link.linked_uid
76
+
77
+ kwargs = {}
78
+ @block.parameters.each do |(param_type, name)|
79
+ case param_type
80
+ when :keyreq, :key
81
+ kwargs[name] = params[name] if params.key?(name)
82
+ when :keyrest
83
+ kwargs = params
84
+ end
85
+ end
86
+
87
+ DSL::ThreadLocal.thread_local(**@thread_locals) do
88
+ @block.call(event, **kwargs)
89
+ rescue Exception => e
90
+ @block.binding.eval("self").logger.log_exception(e)
91
+ end
92
+ end
93
+ end
94
+ private_constant :Profile
95
+ # rubocop:enable Naming/MethodName
96
+
97
+ def initialize
98
+ @profiles = {}
99
+ end
100
+
101
+ # @!visibility private
102
+ def register(uid, block)
103
+ @profiles[uid] = [DSL::ThreadLocal.persist, block]
104
+ end
105
+
106
+ def createProfile(type, callback, context) # rubocop:disable Naming/MethodName
107
+ @profiles[type].then { |(thread_locals, block)| Profile.new(callback, context, type, thread_locals, block) }
108
+ end
109
+
110
+ def getSupportedProfileTypeUIDs # rubocop:disable Naming/MethodName
111
+ @profiles.keys
112
+ end
113
+ end
114
+
115
+ registration = OSGi.register_service(ProfileFactory.instance)
116
+ ScriptHandlingCallbacks.script_unloaded_hooks << -> { registration.unregister }
117
+ end
118
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ #
6
+ # Manages script loading and unloading
7
+ #
8
+ # @!visibility private
9
+ module ScriptHandlingCallbacks
10
+ class << self
11
+ #
12
+ # Return script_loaded_hooks
13
+ #
14
+ # @!visibility private
15
+ def script_loaded_hooks
16
+ @script_loaded_hooks ||= []
17
+ end
18
+
19
+ #
20
+ # Return script_unloaded_hooks
21
+ #
22
+ # @!visibility private
23
+ def script_unloaded_hooks
24
+ @script_unloaded_hooks ||= []
25
+ end
26
+ end
27
+
28
+ #
29
+ # Executed when OpenHAB unloads a script file
30
+ #
31
+ def scriptUnloaded # rubocop:disable Naming/MethodName method name dictated by OpenHAB
32
+ logger.trace("Script unloaded")
33
+ ScriptHandlingCallbacks.script_unloaded_hooks.each do |hook|
34
+ hook.call
35
+ rescue => e
36
+ logger.error("Failed to call script_unloaded hook #{hook}: #{e}")
37
+ end
38
+ end
39
+
40
+ #
41
+ # Executed when OpenHAB loads a script file
42
+ #
43
+ def scriptLoaded(filename) # rubocop:disable Naming/MethodName method name dictated by OpenHAB
44
+ logger.trace("Script loaded: #{filename}")
45
+ ScriptHandlingCallbacks.script_loaded_hooks.each do |hook|
46
+ hook.call
47
+ rescue => e
48
+ logger.error("Failed to call script_loaded hook #{hook}: #{e}")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ singleton_class.include(OpenHAB::Core::ScriptHandlingCallbacks)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Things
8
+ java_import org.openhab.core.thing.Channel
9
+
10
+ #
11
+ # {Channel} is a part of a {Thing} that represents a functionality of it.
12
+ # Therefore {GenericItem Items} can be linked a to a channel.
13
+ #
14
+ # @!attribute [r] item
15
+ # (see ChannelUID#item)
16
+ #
17
+ # @!attribute [r] items
18
+ # (see ChannelUID#items)
19
+ #
20
+ # @!attribute [r] thing
21
+ # (see ChannelUID#thing)
22
+ #
23
+ # @!attribute [r] uid
24
+ # @return [ChannelUID]
25
+ #
26
+ class Channel
27
+ extend Forwardable
28
+
29
+ delegate %i[item items thing] => :uid
30
+
31
+ # @return [String]
32
+ def inspect
33
+ r = "#<OpenHAB::Core::Things::Channel #{uid}"
34
+ r += " #{label.inspect}" if label
35
+ r += " auto_update_policy=#{auto_update_policy}" if auto_update_policy
36
+ r += " configuration=#{configuration.properties.to_h}" unless configuration.properties.empty?
37
+ r += " properties=#{properties.to_h}" unless properties.empty?
38
+ "#{r}>"
39
+ end
40
+
41
+ # @return [String]
42
+ def to_s
43
+ uid.to_s
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Things
8
+ java_import org.openhab.core.thing.ChannelUID
9
+
10
+ #
11
+ # {ChannelUID} represents a unique identifier for {Channel channels}.
12
+ #
13
+ class ChannelUID
14
+ #
15
+ # @attribute [r] thing
16
+ #
17
+ # Return the thing this channel is associated with.
18
+ #
19
+ # @return [Thing, nil]
20
+ #
21
+ def thing
22
+ EntityLookup.lookup_thing(thing_uid)
23
+ end
24
+
25
+ #
26
+ # @attribute [r] item
27
+ #
28
+ # Return the item if this channel is linked with an item. If a channel is linked to more than one item,
29
+ # this method only returns the first item.
30
+ #
31
+ # @return [GenericItem, nil]
32
+ #
33
+ def item
34
+ items.first
35
+ end
36
+
37
+ #
38
+ # @attribute [r] items
39
+ #
40
+ # Returns all of the channel's linked items.
41
+ #
42
+ # @return [Array<GenericItem>] An array of things or an empty array
43
+ #
44
+ def items
45
+ registry = OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
46
+ registry.get_linked_items(self).map { |i| Items::Proxy.new(i) }
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Things
6
+ java_import org.openhab.core.thing.link.ItemChannelLink
7
+
8
+ #
9
+ # Represents the link between a {GenericItem} and a {Thing Thing's}
10
+ # {Channel}.
11
+ #
12
+ # @!attribute [r] thing
13
+ # @return [Thing]
14
+ #
15
+ # @!attribute [r] channel_uid
16
+ # @return [ChannelUID]
17
+ #
18
+ class ItemChannelLink
19
+ extend Forwardable
20
+
21
+ def_delegator :linked_uid, :thing
22
+
23
+ # @!attribute [r] item
24
+ # @return [GenericItem]
25
+ def item
26
+ DSL.items[item_name]
27
+ end
28
+
29
+ alias_method :channel_uid, :linked_uid
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Things
6
+ #
7
+ # Contains methods for {OpenHAB::DSL.profile profile}'s callback to forward commands between items
8
+ # and channels.
9
+ #
10
+ module ProfileCallback
11
+ class << self
12
+ #
13
+ # Wraps the parent class's method to format non-Types.
14
+ #
15
+ # @!macro def_state_parsing_method
16
+ # @!method $1($2)
17
+ # @return [void]
18
+ # @!visibility private
19
+ def def_state_parsing_method(method, param_name)
20
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
21
+ def #{method}(type) # def handle_command(type)
22
+ type = link.item.format_#{param_name == :state ? :update : param_name}(type) # type = link.item.format_command(type)
23
+ super(type) # super(type)
24
+ end # end
25
+ RUBY
26
+ end
27
+ end
28
+
29
+ #
30
+ # Forward the given command to the respective thing handler.
31
+ #
32
+ # @param [Command] command
33
+ #
34
+ def_state_parsing_method(:handle_command, :command)
35
+
36
+ #
37
+ # Send a command to the framework.
38
+ #
39
+ # @param [Command] command
40
+ #
41
+ def_state_parsing_method(:send_command, :command)
42
+
43
+ #
44
+ # Send a state update to the framework.
45
+ #
46
+ # @param [State] state
47
+ #
48
+ def_state_parsing_method(:send_update, :state)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "forwardable"
5
+
6
+ module OpenHAB
7
+ module Core
8
+ module Things
9
+ # Class is a proxy to underlying thing
10
+ # @!visibility private
11
+ class Proxy < Delegator
12
+ extend Forwardable
13
+ def_delegators :__getobj__, :class, :is_a?, :kind_of?
14
+
15
+ # Returns the list of channels associated with this Thing
16
+ #
17
+ # @note This is defined on this class, and not on {Thing}, because
18
+ # that's the interface and if you define it there, it will be hidden
19
+ # by the method on ThingImpl.
20
+ #
21
+ # @return [Array] channels
22
+ def channels
23
+ Thing::ChannelsArray.new(super.to_a)
24
+ end
25
+
26
+ #
27
+ # Set the proxy item (called by super)
28
+ #
29
+ def __setobj__(thing)
30
+ @uid = thing.uid
31
+ end
32
+
33
+ #
34
+ # Lookup thing from thing registry
35
+ #
36
+ def __getobj__
37
+ $things.get(@uid)
38
+ end
39
+
40
+ #
41
+ # Need to check if `self` _or_ the delegate is an instance of the
42
+ # given class
43
+ #
44
+ # So that {#==} can work
45
+ #
46
+ # @return [true, false]
47
+ #
48
+ # @!visibility private
49
+ def instance_of?(klass)
50
+ __getobj__.instance_of?(klass) || super
51
+ end
52
+
53
+ #
54
+ # Check if delegates are equal for comparison
55
+ #
56
+ # Otherwise items can't be used in Java maps
57
+ #
58
+ # @return [true, false]
59
+ #
60
+ # @!visibility private
61
+ def ==(other)
62
+ return __getobj__ == other.__getobj__ if other.instance_of?(Proxy)
63
+
64
+ super
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end