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,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Types
6
+ # @interface
7
+ Type = org.openhab.core.types.Type
8
+
9
+ # @interface
10
+ Command = org.openhab.core.types.Command
11
+
12
+ # @interface
13
+ State = org.openhab.core.types.State
14
+
15
+ # This is a parent interface for all {State}s and {Command}s. It
16
+ # was introduced as many states can be commands at the same time and vice
17
+ # versa. E.g. a light can have the state {ON} or {OFF} and one can also
18
+ # send {ON} and {OFF} as commands to the device. This duality is captured
19
+ # by this marker interface and allows implementing classes to be both
20
+ # state and command at the same time.
21
+ module Type
22
+ # can't alias because to_s doesn't exist on Type
23
+ # @!visibility private
24
+ def inspect
25
+ to_s
26
+ end
27
+
28
+ #
29
+ # Type Coercion
30
+ #
31
+ # Coerce object to the same Type
32
+ #
33
+ # @param [Type] other object to coerce to the same
34
+ # Type as this one
35
+ #
36
+ # @return [[Type, Type], nil]
37
+ #
38
+ def coerce(other)
39
+ logger.trace("Coercing #{self} (#{self.class}) as a request from #{other.class}")
40
+ return [other.as(self.class), self] if other.is_a?(Type) && other.respond_to?(:as)
41
+ end
42
+
43
+ #
44
+ # Check equality without type conversion
45
+ #
46
+ # @return [true,false] if the same value is represented, without type
47
+ # conversion
48
+ def eql?(other)
49
+ return false unless other.instance_of?(self.class)
50
+
51
+ equals(other)
52
+ end
53
+
54
+ #
55
+ # Case equality
56
+ #
57
+ # @return [true,false] if the values are of the same Type
58
+ # or item state of the same type
59
+ #
60
+ def ===(other)
61
+ logger.trace { "Type (#{self.class}) #{self} === #{other} (#{other.class})" }
62
+ return false unless instance_of?(other.class)
63
+
64
+ eql?(other)
65
+ end
66
+
67
+ #
68
+ # Check equality, including type conversion
69
+ #
70
+ # @return [true,false] if the same value is represented, including
71
+ # type conversions
72
+ #
73
+ def ==(other)
74
+ logger.trace { "(#{self.class}) #{self} == #{other} (#{other.class})" }
75
+ return true if equal?(other)
76
+
77
+ # i.e. ON == OFF, REFRESH == ON, ON == REFRESH
78
+ # (RefreshType isn't really coercible)
79
+ return equals(other) if other.instance_of?(self.class) || is_a?(RefreshType) || other.is_a?(RefreshType)
80
+
81
+ if other.respond_to?(:coerce)
82
+ begin
83
+ return false unless (lhs, rhs = other.coerce(self))
84
+ rescue TypeError
85
+ # this one is a bit odd. 50 (Integer) == ON is internally
86
+ # flipping the argument and calling this method. but it responds
87
+ # to coerce, and then raises a TypeError (from Float???) that
88
+ # it couldn't convert to OnOffType. it probably should have
89
+ # returned nil. catch it and return false instead
90
+ return false
91
+ end
92
+
93
+ return lhs == rhs
94
+ end
95
+
96
+ super
97
+ end
98
+ end
99
+
100
+ #
101
+ # @!parse
102
+ # # This is a marker interface for all command types.
103
+ # module Command
104
+ # include Type
105
+ # end
106
+ #
107
+ # # This is a marker interface for all state types.
108
+ # module State
109
+ # include Type
110
+ # end
111
+ end
112
+ end
113
+ end
114
+
115
+ # @!parse
116
+ # Command = OpenHAB::Core::Types::Command
117
+ # State = OpenHAB::Core::Types::State
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ UnDefType = org.openhab.core.types.UnDefType
9
+
10
+ # There are situations when item states do not have any defined value.
11
+ # This might be because they have not been initialized yet (never
12
+ # received an state update so far) or because their state is ambiguous
13
+ # (e.g. a group item with members whose states do not match will be
14
+ # {NULL}).
15
+ class UnDefType # rubocop:disable Lint/EmptyClass
16
+ # @!parse include State
17
+
18
+ # @!constant NULL
19
+ # Null State
20
+ # @!constant UNDEF
21
+ # Undef State
22
+
23
+ # @!method null?
24
+ # Check if `self == NULL`
25
+ # @return [true,false]
26
+
27
+ # @!method undef?
28
+ # Check if `self == UNDEF`
29
+ # @return [true,false]
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # @!parse
36
+ # UnDefType = OpenHAB::Core::Types::UnDefType
37
+ # NULL = OpenHAB::Core::Types::UnDefType::NULL
38
+ # UNDEF = OpenHAB::Core::Types::UnDefType::UNDEF
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ UpDownType = org.openhab.core.library.types.UpDownType
9
+
10
+ #
11
+ # Implements the {UP} and {DOWN} commands.
12
+ #
13
+ # Also, {PercentType} can be converted to {UpDownType}
14
+ # for more semantic comparisons. `0` is {UP}, `100` is
15
+ # {DOWN}, and anything in-between is neither.
16
+ #
17
+ class UpDownType
18
+ # @!parse include Command, State
19
+
20
+ # @!constant UP
21
+ # Up Command/State
22
+ # @!constant DOWN
23
+ # Down Command/State
24
+
25
+ # @!method up?
26
+ # Check if `self == UP`
27
+ # @return [true,false]
28
+
29
+ # @!method down?
30
+ # Check if `self == DOWN`
31
+ # @return [true,false]
32
+
33
+ #
34
+ # Invert the type
35
+ #
36
+ # @return [UpDownType] {UP} if {down?}, {DOWN} if {up?}
37
+ #
38
+ def !
39
+ return UP if down?
40
+ return DOWN if up?
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # @!parse
48
+ # UpDownType = OpenHAB::Core::Types::UpDownType
49
+ # UP = OpenHAB::Core::Types::UpDownType::UP
50
+ # DOWN = OpenHAB::Core::Types::UpDownType::DOWN
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.expand_path("types/*.rb", __dir__)].sort.each do |f|
4
+ require f
5
+ end
6
+
7
+ module OpenHAB
8
+ module Core
9
+ #
10
+ # Contains the core types that OpenHAB uses as {State}s for items, and
11
+ # {Command}s to be sent to control them.
12
+ #
13
+ # Types are the specific data types that commands and states are. They can be
14
+ # sent to items, be the current state of an item, or be the `command`, `state`,
15
+ # and `was` field of various
16
+ # {group::OpenHAB::DSL::Rules::Builder::Triggers triggers}.
17
+ # Some types have additional useful methods.
18
+ #
19
+ module Types
20
+ # Hash taking a Enum value, and returning two symbols of
21
+ # predicates to be defined for it. the first is the "command" form,
22
+ # which should be defined on ItemCommandEvent, and on the Type itself.
23
+ # the second is "state" form, which should be defined on the applicable
24
+ # Item, and on the Type itself.
25
+ # @!visibility private
26
+ PREDICATE_ALIASES = Hash.new { |_h, k| [:"#{k.downcase}?"] * 2 }
27
+ .merge({
28
+ "PLAY" => %i[play? playing?],
29
+ "PAUSE" => %i[pause? paused?],
30
+ "REWIND" => %i[rewind? rewinding?],
31
+ "FASTFORWARD" => %i[fast_forward? fast_forwarding?]
32
+ }).freeze
33
+
34
+ # Hash taking a Enum value, and returning an array of symbols
35
+ # of the command to define for it
36
+ # @!visibility private
37
+ COMMAND_ALIASES = Hash.new { |_h, k| k.downcase.to_sym }
38
+ .merge({
39
+ "FASTFORWARD" => :fast_forward
40
+ }).freeze
41
+
42
+ constants.map { |c| const_get(c) }
43
+ .grep(Module)
44
+ .select { |k| k < java.lang.Enum }
45
+ .each do |klass|
46
+ # make sure == from Type is inherited
47
+ klass.remove_method(:==)
48
+
49
+ # dynamically define predicate methods
50
+ klass.values.each do |value| # rubocop:disable Style/HashEachMethods this isn't a Ruby hash
51
+ # include all the aliases that we define for items both command and
52
+ # state aliases (since types can be interrogated as an incoming
53
+ # command, or as the state of an item)
54
+ command = :"#{Types::COMMAND_ALIASES[value.to_s]}?"
55
+ states = Types::PREDICATE_ALIASES[value.to_s]
56
+
57
+ ([command] | states).each do |method|
58
+ logger.trace("Defining #{klass}##{method} for #{value}")
59
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
60
+ def #{method} # def on?
61
+ self == #{value} # self == ON
62
+ end # end
63
+ RUBY
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ java_import org.openhab.core.common.AbstractUID
6
+
7
+ # Adds methods to core OpenHAB AbstractUID to make it more natural in Ruby
8
+ class AbstractUID
9
+ # implicit conversion to string
10
+ alias_method :to_str, :to_s
11
+ # inspect result is just the string representation
12
+ alias_method :inspect, :to_s
13
+
14
+ # compares if equal to `other`, including string conversion
15
+ # @return [true, false]
16
+ def ==(other)
17
+ return true if equals(other)
18
+
19
+ to_s == other
20
+ end
21
+ end
22
+
23
+ # have to remove == from all descendant classes so that they'll inherit
24
+ # the new implementation
25
+ [org.openhab.core.items.MetadataKey,
26
+ org.openhab.core.thing.UID,
27
+ org.openhab.core.thing.ChannelUID,
28
+ org.openhab.core.thing.ChannelGroupUID,
29
+ org.openhab.core.thing.ThingUID,
30
+ org.openhab.core.thing.ThingTypeUID,
31
+ org.openhab.core.thing.type.ChannelTypeUID,
32
+ org.openhab.core.thing.type.ChannelGroupTypeUID].each do |klass|
33
+ klass.remove_method(:==)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.expand_path("core/**/*.rb", __dir__)].sort.each do |f|
4
+ require f
5
+ end
6
+
7
+ module OpenHAB
8
+ # Contains classes and modules that wrap actual OpenHAB objects
9
+ module Core
10
+ # The OpenHAB Version. >= 3.3.0 is required.
11
+ # @return [String]
12
+ VERSION = org.openhab.core.OpenHAB.version.freeze
13
+
14
+ unless Gem::Version.new(VERSION) >= Gem::Version.new("3.3.0")
15
+ raise "`openhab-jrubyscripting` requires OpenHAB >= 3.3.0"
16
+ end
17
+
18
+ # @return [Integer] Number of seconds to wait between checks for automation manager
19
+ CHECK_DELAY = 10
20
+ private_constant :CHECK_DELAY
21
+ class << self
22
+ #
23
+ # Wait until OpenHAB engine ready to process
24
+ #
25
+ # @return [void]
26
+ #
27
+ # @!visibility private
28
+ def wait_till_openhab_ready
29
+ logger.trace("Checking readiness of OpenHAB")
30
+ until automation_manager
31
+ logger.trace("Automation manager not loaded, checking again in #{CHECK_DELAY} seconds.")
32
+ sleep CHECK_DELAY
33
+ end
34
+ logger.trace "Automation manager instantiated, OpenHAB ready for rule processing."
35
+ end
36
+
37
+ #
38
+ # @!attribute [r] config_folder
39
+ # @return [Pathname] The configuration folder path.
40
+ #
41
+ def config_folder
42
+ Pathname.new(org.openhab.core.OpenHAB.config_folder)
43
+ end
44
+
45
+ #
46
+ # JRuby isn't respecting $RUBYLIB when run embedded inside of OpenHAB, so do it manually
47
+ #
48
+ # @return [void]
49
+ #
50
+ # @!visibility private
51
+ def add_rubylib_to_load_path
52
+ ENV["RUBYLIB"]&.split(File::PATH_SEPARATOR)&.each do |path|
53
+ next if path.empty?
54
+
55
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
56
+ end
57
+ end
58
+
59
+ #
60
+ # @!attribute [r] automation_manager
61
+ # @return [org.openhab.core.automation.module.script.rulesupport.shared.ScriptedAutomationManager]
62
+ # The OpenHAB Automation manager.
63
+ #
64
+ def automation_manager
65
+ $scriptExtension.get("automationManager")
66
+ end
67
+
68
+ #
69
+ # @!attribute [r] rule_registry
70
+ # @return [org.openhab.core.automation.RuleRegistry] The OpenHAB rule registry
71
+ #
72
+ def rule_registry
73
+ $scriptExtension.get("ruleRegistry")
74
+ end
75
+
76
+ #
77
+ # @!attribute [r] rule_manager
78
+ # @return [org.openhab.core.automation.RuleManager] The OpenHAB rule manager/engine
79
+ #
80
+ def rule_manager
81
+ @rule_manager ||= OSGi.service("org.openhab.core.automation.RuleManager")
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module CoreExt
5
+ module Java
6
+ Duration = java.time.Duration
7
+
8
+ # Extensions to Duration
9
+ class Duration
10
+ # @!parse include TemporalAmount
11
+
12
+ alias_method :to_i, :seconds
13
+
14
+ #
15
+ # Convert to number of seconds
16
+ #
17
+ # @return [Float]
18
+ #
19
+ def to_f
20
+ to_i + (nano / 1_000_000_000.0)
21
+ end
22
+
23
+ remove_method :==
24
+
25
+ # @return [Integer, nil]
26
+ def <=>(other)
27
+ return to_f <=> other if other.is_a?(Numeric)
28
+
29
+ super
30
+ end
31
+
32
+ #
33
+ # Converts `other` to {Duration}, if possible.
34
+ #
35
+ # @param [Numeric, Period] other
36
+ # @return [Array, nil]
37
+ #
38
+ def coerce(other)
39
+ return [other.seconds, self] if other.is_a?(Numeric)
40
+ return [other.to_i.seconds, self] if other.is_a?(Period)
41
+ end
42
+
43
+ {
44
+ plus: :+,
45
+ minus: :-
46
+ }.each do |java_op, ruby_op|
47
+ # def +(other)
48
+ # if other.is_a?(Duration)
49
+ # plus(other)
50
+ # elsif other.is_a?(Integer)
51
+ # plus_seconds(other)
52
+ # elsif other.is_a?(Numeric)
53
+ # plus(other.seconds)
54
+ # elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
55
+ # lhs + rhs
56
+ # else
57
+ # raise TypeError, "#{other.class} can't be coerced into Duration"
58
+ # end
59
+ # end
60
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
61
+ def #{ruby_op}(other)
62
+ if other.is_a?(Duration)
63
+ #{java_op}(other)
64
+ elsif other.is_a?(Integer)
65
+ #{java_op}_seconds(other)
66
+ elsif other.is_a?(Numeric)
67
+ #{java_op}(other.seconds)
68
+ elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
69
+ lhs #{ruby_op} rhs
70
+ else
71
+ raise TypeError, "\#{other.class} can't be coerced into Duration"
72
+ end
73
+ end
74
+ RUBY
75
+ end
76
+
77
+ {
78
+ multipliedBy: :*,
79
+ dividedBy: :/
80
+ }.each do |java_op, ruby_op|
81
+ # def *(other)
82
+ # if other.is_a?(Integer)
83
+ # multipliedBy(other)
84
+ # elsif other.is_a?(Numeric)
85
+ # Duration.of_seconds(to_f * other)
86
+ # elsif other.is_a?(Duration)
87
+ # Duration.of_seconds(to_f * other.to_f)
88
+ # elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
89
+ # lhs * rhs
90
+ # else
91
+ # raise TypeError, "#{other.class} can't be coerced into Duration"
92
+ # end
93
+ # end
94
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
95
+ def #{ruby_op}(other)
96
+ if other.is_a?(Integer)
97
+ #{java_op}(other)
98
+ elsif other.is_a?(Numeric)
99
+ Duration.of_seconds(to_f #{ruby_op} other)
100
+ elsif other.is_a?(Duration)
101
+ Duration.of_seconds(to_f #{ruby_op} other.to_f)
102
+ elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
103
+ lhs #{ruby_op} rhs
104
+ else
105
+ raise TypeError, "\#{other.class} can't be coerced into Duration"
106
+ end
107
+ end
108
+ RUBY
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ # @!parse Duration = OpenHAB::CoreExt::Java::Duration
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "time"
4
+
5
+ module OpenHAB
6
+ module CoreExt
7
+ module Java
8
+ java_import java.time.LocalDate
9
+
10
+ # Extensions to LocalDate
11
+ class LocalDate
12
+ include Time
13
+
14
+ class << self # rubocop:disable Lint/EmptyClass
15
+ # @!attribute [r] now
16
+ # @return [ZonedDateTime]
17
+ end
18
+
19
+ # @param [TemporalAmount, LocalDate, Numeric] other
20
+ # If other is a Numeric, it's interpreted as days.
21
+ # @return [LocalDate] If other is a TemporalAmount or Numeric
22
+ # @return [Period] If other is a LocalDate
23
+ def -(other)
24
+ case other
25
+ when Date
26
+ Period.of_days(day_of_year - other.yday)
27
+ when MonthDay
28
+ self - other.at_year(year)
29
+ when LocalDate
30
+ Period.of_days(day_of_year - other.day_of_year)
31
+ when Duration
32
+ minus_days(other.to_days)
33
+ when Numeric
34
+ minus_days(other.ceil)
35
+ else
36
+ minus(other)
37
+ end
38
+ end
39
+
40
+ # @param [TemporalAmount, Numeric] other
41
+ # If other is a Numeric, it's interpreted as days.
42
+ # @return [LocalDate]
43
+ def +(other)
44
+ case other
45
+ when Duration
46
+ plus_days(other.to_days)
47
+ when Numeric
48
+ plus_days(other.to_i)
49
+ else
50
+ plus(other)
51
+ end
52
+ end
53
+
54
+ #
55
+ # Returns the next day
56
+ #
57
+ # @return [LocalDate]
58
+ #
59
+ def succ
60
+ plus_days(1)
61
+ end
62
+
63
+ # @return [Date]
64
+ def to_date
65
+ Date.new(year, month_value, day_of_month)
66
+ end
67
+
68
+ alias_method :to_month, :month
69
+
70
+ # @return [MonthDay]
71
+ def to_month_day
72
+ MonthDay.of(month, day_of_month)
73
+ end
74
+
75
+ # @return [self]
76
+ def to_local_date(_context = nil)
77
+ self
78
+ end
79
+
80
+ # @param [ZonedDateTime, nil] context
81
+ # A {ZonedDateTime} used to fill in missing fields
82
+ # during conversion. {ZonedDateTime.now} is assumed if not given.
83
+ # @return [ZonedDateTime]
84
+ def to_zoned_date_time(context = nil)
85
+ zone = context&.zone || java.time.ZoneId.system_default
86
+ at_start_of_day(zone)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ LocalDate = OpenHAB::CoreExt::Java::LocalDate unless Object.const_defined?(:LocalDate)