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,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ PlayPauseType = org.openhab.core.library.types.PlayPauseType
9
+
10
+ # Implements {PLAY} and {PAUSE} commands and states.
11
+ class PlayPauseType # rubocop:disable Lint/EmptyClass
12
+ # @!parse include Command, State
13
+
14
+ # @!constant PLAY
15
+ # Play Command/Playing State
16
+ # @!constant PAUSE
17
+ # Pause Command/Paused State
18
+
19
+ # @!method playing?
20
+ # Check if `self == PLAY`
21
+ # @return [true,false]
22
+
23
+ # @!parse alias play? playing?
24
+
25
+ # @!method paused?
26
+ # Check if `self == PAUSE`
27
+ # @return [true,false]
28
+
29
+ # @!parse alias pause? paused?
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # @!parse
36
+ # PlayPauseType = OpenHAB::Core::Types::PlayPauseType
37
+ # PLAY = OpenHAB::Core::Types::PlayPauseType::PLAY
38
+ # PAUSE = OpenHAB::Core::Types::PlayPauseType::PAUSE
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ PointType = org.openhab.core.library.types.PointType
9
+
10
+ # {PointType} can be used for items that are dealing with GPS or location awareness functionality.
11
+ class PointType
12
+ # @!parse include Command, State
13
+
14
+ # @overload initialize(latitude, longitude, altitude)
15
+ # @param [DecimalType, QuantityType, StringType, Numeric] latitude
16
+ # @param [DecimalType, QuantityType, StringType, Numeric] longitude
17
+ # @param [DecimalType, QuantityType, StringType, Numeric] altitude
18
+ def initialize(*args)
19
+ if (2..3).cover?(args.length)
20
+ args = args.each_with_index.map do |value, index|
21
+ if value.is_a?(DecimalType) || value.is_a?(StringType)
22
+ value
23
+ elsif value.is_a?(QuantityType)
24
+ unit = index == 2 ? DSL.unit(SIUnits::METRE.dimension) || SIUnits::METRE : Units::DEGREE_ANGLE
25
+ DecimalType.new(value.to_unit(unit).to_big_decimal)
26
+ elsif value.respond_to?(:to_str)
27
+ StringType.new(value.to_str)
28
+ elsif value.respond_to?(:to_d)
29
+ DecimalType.new(value)
30
+ end
31
+ end
32
+ end
33
+
34
+ super(*args)
35
+ end
36
+
37
+ #
38
+ # Check equality without type conversion
39
+ #
40
+ # @return [true,false] if the same value is represented, without type
41
+ # conversion
42
+ def eql?(other)
43
+ return false unless other.instance_of?(self.class)
44
+
45
+ equals(other)
46
+ end
47
+
48
+ #
49
+ # Check equality with type conversion
50
+ #
51
+ # @param [PointType, String]
52
+ # other object to compare to
53
+ #
54
+ # @return [true,false]
55
+ #
56
+ def ==(other)
57
+ logger.trace { "(#{self.class}) #{self} == #{other} (#{other.class})" }
58
+ if other.instance_of?(self.class)
59
+ equals(other)
60
+ elsif other.respond_to?(:coerce)
61
+ return false unless (lhs, rhs = other.coerce(self))
62
+
63
+ lhs == rhs
64
+ end
65
+ end
66
+
67
+ # rename raw methods so we can overwrite them
68
+ # @!visibility private
69
+ alias_method :raw_latitude, :latitude
70
+ # .
71
+ # @!visibility private
72
+ alias_method :raw_longitude, :longitude
73
+ # .
74
+ # @!visibility private
75
+ alias_method :raw_altitude, :altitude
76
+ # .
77
+ # @!visibility private
78
+ alias_method :raw_distance_from, :distance_from
79
+
80
+ # @!attribute [r] latitude
81
+ # @return [QuantityType]
82
+ def latitude
83
+ QuantityType.new(raw_latitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
84
+ end
85
+
86
+ # @!attribute [r] longitude
87
+ # @return [QuantityType]
88
+ def longitude
89
+ QuantityType.new(raw_longitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
90
+ end
91
+
92
+ # @!attribute [r] altitude
93
+ # @return [QuantityType]
94
+ def altitude
95
+ QuantityType.new(raw_altitude.to_big_decimal, Units::METRE)
96
+ end
97
+
98
+ #
99
+ # Calculate the distance in meters from other, ignoring altitude.
100
+ #
101
+ # This algorithm also ignores the oblate spheroid shape of Earth and
102
+ # assumes a perfect sphere, so results are inexact.
103
+ #
104
+ # @return [QuantityType]
105
+ def distance_from(other)
106
+ logger.trace("(#{self}).distance_from(#{other} (#{other.class})")
107
+ raise TypeError, "#{other.class} can't be coerced into #{self.class}" unless other.is_a?(PointType)
108
+
109
+ QuantityType.new(raw_distance_from(other), SIUnits::METRE)
110
+ end
111
+ alias_method :-, :distance_from
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ # @!parse PointType = OpenHAB::Core::Types::PointType
@@ -0,0 +1,327 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "numeric_type"
4
+ require_relative "type"
5
+
6
+ module OpenHAB
7
+ module Core
8
+ module Types
9
+ QuantityType = org.openhab.core.library.types.QuantityType
10
+
11
+ #
12
+ # {QuantityType} extends {DecimalType} to handle physical unit measurement.
13
+ #
14
+ # {QuantityType} is part of the [Units of Measurement](https://www.openhab.org/docs/concepts/units-of-measurement.html)
15
+ # framework in OpenHAB. It is represented as a decimal number with a unit.
16
+ # You can construct a {QuantityType} object by using the pipe operator with any Numeric.
17
+ #
18
+ # @example QuantityTypes can perform math operations between them.
19
+ # (50 | "°F") + (-25 | "°F") # => 25.0 °F
20
+ # (100 | "°F") / (2 | "°F") # => 50
21
+ # (50 | "°F") - (25 | "°F") # => 25 °F
22
+ # (50 | "°F") + (50 | "°F") # => 100 °F
23
+ #
24
+ # @example If the operand is a number, it will be unit-less, but the result of the operation will have a unit. This only works for multiplication and division.
25
+ # (50 | "°F") * 2 # => 100 °F
26
+ # (100 | "°F") / 2 # => 50 °F
27
+ #
28
+ # @example If the operand is a dimensioned NumberItem it will automatically be converted to a quantity for the operation.
29
+ # # NumberF = "2 °F"
30
+ # # NumberC = "2 °C"
31
+ # (50 | "°F") + NumberF.state # => 52.0 °F
32
+ # (50 | "°F") + NumberC.state # => 85.60 °F
33
+ #
34
+ # @example If the operand is a non-dimensioned NumberItem it can be used only in multiplication and division operations.
35
+ # # Number Dimensionless = 2
36
+ # (50 | "°F") * Dimensionless.state # => 100 °F
37
+ # (50 | "°F") / Dimensionless.state # => 25 °F
38
+ #
39
+ # @example Quantities can be compared, if they have comparable units.
40
+ # (50 | "°F") > (25 | "°F")
41
+ # (50 | "°F") > (525 | "°F")
42
+ # (50 | "°F") >= (50 | "°F")
43
+ # (50 | "°F") == (50 | "°F")
44
+ # (50 | "°F") < (25 | "°C")
45
+ #
46
+ # @example A Range can be used with QuantityType:
47
+ # ((0 | "°C")..(100 | "°C")).cover?(NumberC)
48
+ #
49
+ # @example A Range can also be used in a case statement for a dimensioned item:
50
+ # description = case NumberC.state
51
+ # when (-20 | "°C")...(18 | "°C") then "too cold"
52
+ # when (18 | "°C")...(25 | "°C") then "comfortable"
53
+ # when (25 | "°C")...(40 | "°C") then "too warm"
54
+ # else "out of range"
55
+ # end
56
+ #
57
+ # @example Dimensioned Number Items can be converted to quantities with other units using the | operator
58
+ # # NumberC = "23 °C"
59
+ #
60
+ # # Using a unit
61
+ # logger.info("In Fahrenheit #{NumberC.state | ImperialUnits::FAHRENHEIT }")
62
+ #
63
+ # # Using a string
64
+ # logger.info("In Fahrenheit #{NumberC.state | "°F"}")
65
+ #
66
+ # @example Dimensionless Number Items can be converted to quantities with units using the | operator
67
+ # # Dimensionless = 70
68
+ #
69
+ # # Using a unit
70
+ # logger.info("In Fahrenheit #{Dimensionless.state | ImperialUnits::FAHRENHEIT }")
71
+ #
72
+ # # Using a string
73
+ # logger.info("In Fahrenheit #{Dimensionless.state | "°F"}")
74
+ #
75
+ # @example Dimensioned Number Items automatically use their units and convert automatically for math operations
76
+ # # Number:Temperature NumberC = 23 °C
77
+ # # Number:Temperature NumberF = 70 °F
78
+ # NumberC.state - NumberF.state # => 1.88 °C
79
+ # NumberF.state + NumberC.state # => 143.40 °F
80
+ #
81
+ # @example Dimensionless Number Items can be used for multiplication and division.
82
+ # # Number Dimensionless = 2
83
+ # # Number:Temperature NumberF = 70 °F
84
+ # NumberF.state * Dimensionless.state # => 140.0 °F
85
+ # NumberF.state / Dimensionless.state # => 35.0 °F
86
+ # Dimensionless.state * NumberF.state # => 140.0 °F
87
+ # 2 * NumberF.state # => 140.0 °F
88
+ #
89
+ # @example Comparisons work on dimensioned number items with different, but comparable units.
90
+ # # Number:Temperature NumberC = 23 °C
91
+ # # Number:Temperature NumberF = 70 °F
92
+ # NumberC.state > NumberF.state # => true
93
+ #
94
+ # @example For certain unit types, such as temperature, all unit needs to be normalized to the comparator for all operations when combining comparison operators with dimensioned numbers.
95
+ # (NumberC.state | "°F") - (NumberF.state | "°F") < 4 | "°F"
96
+ #
97
+ class QuantityType
98
+ # @!parse include Command, State
99
+ include NumericType
100
+ include ComparableType
101
+
102
+ # @!parse
103
+ # #
104
+ # # Convert this {QuantityType} into another unit.
105
+ # #
106
+ # # @param [String, javax.measure.units.Unit] unit
107
+ # # @return [QuantityType]
108
+ # #
109
+ # # @example
110
+ # # NumberC.state | ImperialUnits::FAHRENHEIT
111
+ # #
112
+ # def to_unit(unit); end
113
+
114
+ alias_method :|, :to_unit
115
+
116
+ #
117
+ # Comparison
118
+ #
119
+ # Comparisons against Numeric and DecimalType are allowed only within a
120
+ # {OpenHAB::DSL.unit unit} block to avoid unit ambiguities.
121
+ # Comparisons against other types may be done if supported by that type's coercion.
122
+ #
123
+ # @param [QuantityType, DecimalType, Numeric, Object]
124
+ # other object to compare to
125
+ #
126
+ # @return [Integer, nil] -1, 0, +1 depending on whether `other` is
127
+ # less than, equal to, or greater than self
128
+ #
129
+ # `nil` is returned if the two values are incomparable.
130
+ #
131
+ def <=>(other)
132
+ logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
133
+ case other
134
+ when self.class
135
+ return unitize(other.unit).compare_to(other) if unit == Units::ONE
136
+ return compare_to(other.unitize(unit)) if other.unit == Units::ONE
137
+
138
+ return compare_to(other)
139
+ when Numeric, DecimalType
140
+ if (unit = OpenHAB::DSL.unit(dimension))
141
+ return compare_to(QuantityType.new(other, unit))
142
+ end
143
+
144
+ return nil # don"t allow comparison with numeric outside a unit block
145
+ end
146
+
147
+ return nil unless other.respond_to?(:coerce)
148
+
149
+ other.coerce(self)&.then { |lhs, rhs| lhs <=> rhs }
150
+ end
151
+
152
+ #
153
+ # Type Coercion
154
+ #
155
+ # Coerce object to a {QuantityType}
156
+ #
157
+ # @param [Numeric, Type] other object to coerce to a {QuantityType}
158
+ #
159
+ # if `other` is a {Type}, `self` will instead be coerced
160
+ # to that type to accomodate comparison with things such as {OnOffType}
161
+ #
162
+ # @return [Array<(QuantityType, QuantityType)>, nil]
163
+ def coerce(other)
164
+ logger.trace("Coercing #{self} as a request from #{other.class}")
165
+ if other.is_a?(Type)
166
+ [other, as(other.class)]
167
+ elsif other.respond_to?(:to_d)
168
+ [QuantityType.new(other.to_d.to_java, Units::ONE), self]
169
+ end
170
+ end
171
+
172
+ # arithmetic operators
173
+ alias_method :-@, :negate
174
+
175
+ {
176
+ add: :+,
177
+ subtract: :-
178
+ }.each do |java_op, ruby_op|
179
+ convert = "self.class.new(other, DSL.unit(dimension) || unit)"
180
+
181
+ class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
182
+ # def +(other)
183
+ # logger.trace("#{self} + #{other} (#{other.class})")
184
+ # if other.is_a?(QuantityType)
185
+ # add_quantity(other)
186
+ # elsif other.is_a?(DecimalType)
187
+ # other = other.to_big_decimal
188
+ # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
189
+ # elsif other.is_a?(java.math.BigDecimal)
190
+ # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
191
+ # elsif other.respond_to?(:to_d)
192
+ # other = other.to_d.to_java
193
+ # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
194
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
195
+ # lhs + rhs
196
+ # else
197
+ # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
198
+ # end
199
+ # end
200
+ <<~RUBY, __FILE__, __LINE__ + 1
201
+ def #{ruby_op}(other)
202
+ logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
203
+ if other.is_a?(QuantityType)
204
+ #{java_op}_quantity(other)
205
+ elsif other.is_a?(DecimalType)
206
+ other = other.to_big_decimal
207
+ #{java_op}_quantity(#{convert})
208
+ elsif other.is_a?(java.math.BigDecimal)
209
+ #{java_op}_quantity(#{convert})
210
+ elsif other.respond_to?(:to_d)
211
+ other = other.to_d.to_java
212
+ #{java_op}_quantity(#{convert})
213
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
214
+ lhs #{ruby_op} rhs
215
+ else
216
+ raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
217
+ end
218
+ end
219
+ RUBY
220
+ )
221
+ end
222
+
223
+ {
224
+ multiply: :*,
225
+ divide: :/
226
+ }.each do |java_op, ruby_op|
227
+ class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
228
+ # def *(other)
229
+ # logger.trace("#{self} * #{other} (#{other.class})")
230
+ # if other.is_a?(QuantityType)
231
+ # multiply_quantity(other)
232
+ # elsif other.is_a?(DecimalType)
233
+ # multiply(other.to_big_decimal)
234
+ # elsif other.is_a?(java.math.BigDecimal)
235
+ # multiply(other)
236
+ # elsif other.respond_to?(:to_d)
237
+ # multiply(other.to_d.to_java)
238
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
239
+ # lhs * rhs
240
+ # else
241
+ # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
242
+ # end
243
+ # end
244
+ <<~RUBY, __FILE__, __LINE__ + 1
245
+ def #{ruby_op}(other)
246
+ logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
247
+ if other.is_a?(QuantityType)
248
+ #{java_op}_quantity(other)
249
+ elsif other.is_a?(DecimalType)
250
+ #{java_op}(other.to_big_decimal)
251
+ elsif other.is_a?(java.math.BigDecimal)
252
+ #{java_op}(other)
253
+ elsif other.respond_to?(:to_d)
254
+ #{java_op}(other.to_d.to_java)
255
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
256
+ lhs #{ruby_op} rhs
257
+ else
258
+ raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
259
+ end
260
+ end
261
+ RUBY
262
+ )
263
+ end
264
+
265
+ # if it's a dimensionless quantity, change the unit to match other_unit
266
+ # @!visibility private
267
+ def unitize(other_unit = unit)
268
+ # prefer converting to the thread-specified unit if there is one
269
+ other_unit = DSL.unit(dimension) || other_unit
270
+ logger.trace("Converting #{self} to #{other_unit}")
271
+
272
+ case unit
273
+ when Units::ONE
274
+ QuantityType.new(to_big_decimal, other_unit)
275
+ when other_unit
276
+ self
277
+ else
278
+ to_unit(other_unit)
279
+ end
280
+ end
281
+
282
+ # if unit is {org.openhab.core.library.unit.Units.ONE}, return a plain
283
+ # Java BigDecimal
284
+ # @!visibility private
285
+ def deunitize
286
+ return to_big_decimal if unit == Units::ONE
287
+
288
+ self
289
+ end
290
+
291
+ private
292
+
293
+ # do addition directly against a QuantityType while ensuring we unitize
294
+ # both sides
295
+ def add_quantity(other)
296
+ unitize(other.unit).add(other.unitize(unit))
297
+ end
298
+
299
+ # do subtraction directly against a QuantityType while ensuring we
300
+ # unitize both sides
301
+ def subtract_quantity(other)
302
+ unitize(other.unit).subtract(other.unitize(unit))
303
+ end
304
+
305
+ # do multiplication directly against a QuantityType while ensuring
306
+ # we deunitize both sides, and also invert the operation if one side
307
+ # isn't actually a unit
308
+ def multiply_quantity(other)
309
+ lhs = deunitize
310
+ rhs = other.deunitize
311
+ # reverse the arguments if it's multiplication and the LHS isn"t a QuantityType
312
+ lhs, rhs = rhs, lhs if lhs.is_a?(java.math.BigDecimal)
313
+ # what a waste... using a QuantityType to multiply two dimensionless quantities
314
+ # have to make sure lhs is still a QuantityType in order to return a new
315
+ # QuantityType that's still dimensionless
316
+ lhs = other if lhs.is_a?(java.math.BigDecimal)
317
+
318
+ lhs.multiply(rhs)
319
+ end
320
+
321
+ alias_method :divide_quantity, :divide
322
+ end
323
+ end
324
+ end
325
+ end
326
+
327
+ # @!parse QuantityType = OpenHAB::Core::Types::QuantityType
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ RawType = org.openhab.core.library.types.RawType
9
+
10
+ #
11
+ # This type can be used for all binary data such as images, documents, sounds etc.
12
+ #
13
+ class RawType # rubocop:disable Lint/EmptyClass
14
+ # @!parse include State
15
+
16
+ # @!method mime_type
17
+ # @return [String]
18
+
19
+ # @!method bytes
20
+ # @return [String]
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # @!parse RawType = OpenHAB::Core::Types::RawType
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ RefreshType = org.openhab.core.types.RefreshType
9
+
10
+ # Implements the {REFRESH} command.
11
+ class RefreshType # rubocop:disable Lint/EmptyClass
12
+ # @!parse include Command
13
+
14
+ # @!constant REFRESH
15
+ # Refresh Command
16
+
17
+ # @!method refresh?
18
+ # Check if `self == REFRESH`
19
+ # @return [true,false]
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ # @!parse
26
+ # RefreshType = OpenHAB::Core::Types::RefreshType
27
+ # REFRESH = OpenHAB::Core::Types::RefreshType::REFRESH
@@ -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
+ RewindFastforwardType = org.openhab.core.library.types.RewindFastforwardType
9
+
10
+ # Implements the {REWIND} and {FASTFORWARD} commands and states.
11
+ class RewindFastforwardType # rubocop:disable Lint/EmptyClass
12
+ # @!parse include Command, State
13
+
14
+ # @!constant REWIND
15
+ # Rewind Command/Rewinding State
16
+ # @!constant FASTFORWARD
17
+ # Fast Forward Command/Fast Forwarding State
18
+
19
+ # @!method rewinding?
20
+ # Check if `self == REWIND`
21
+ # @return [true,false]
22
+
23
+ # @!parse alias rewind? rewinding?
24
+
25
+ # @!method fast_forwarding?
26
+ # Check if `self == FASTFORWARD`
27
+ # @return [true,false]
28
+
29
+ # @!parse alias fast_forward? fast_forwarding?
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # @!parse
36
+ # RewindFastforwardType = OpenHAB::Core::Types::RewindFastforwardType
37
+ # REWIND = OpenHAB::Core::Types::RewindFastforwardType::REWIND
38
+ # FASTFORWARD = OpenHAB::Core::Types::RewindFastforwardType::FASTFORWARD
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "type"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Types
8
+ StopMoveType = org.openhab.core.library.types.StopMoveType
9
+
10
+ # Implements the {STOP} and {MOVE} commands.
11
+ class StopMoveType # rubocop:disable Lint/EmptyClass
12
+ # @!parse include Command
13
+
14
+ # @!constant STOP
15
+ # Stop Command
16
+ # @!constant MOVE
17
+ # Move Command
18
+
19
+ # @!method stop?
20
+ # Check if `self == STOP`
21
+ # @return [true,false]
22
+
23
+ # @!method move?
24
+ # Check if `self == MOVE`
25
+ # @return [true,false]
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # @!parse
32
+ # StopMoveType = OpenHAB::Core::Types::StopMoveType
33
+ # STOP = OpenHAB::Core::Types::StopMoveType::STOP
34
+ # MOVE = OpenHAB::Core::Types::StopMoveType::MOVE
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require_relative "comparable_type"
6
+ require_relative "type"
7
+
8
+ module OpenHAB
9
+ module Core
10
+ module Types
11
+ StringType = org.openhab.core.library.types.StringType
12
+
13
+ # {StringType} represents a String as a {Type} and a {Command}.
14
+ class StringType
15
+ # @!parse include Command, State
16
+
17
+ extend Forwardable
18
+ include Comparable
19
+ include ComparableType
20
+
21
+ #
22
+ # Check equality without type conversion
23
+ #
24
+ # @return [true,false] if the same value is represented, without type
25
+ # conversion
26
+ def eql?(other)
27
+ return false unless other.instance_of?(self.class)
28
+
29
+ to_s.compare_to(other.to_s).zero?
30
+ end
31
+
32
+ #
33
+ # Comparison
34
+ #
35
+ # @param [StringType, String]
36
+ # other object to compare to
37
+ #
38
+ # @return [Integer, nil] -1, 0, +1 depending on whether `other` is
39
+ # less than, equal to, or greater than self
40
+ #
41
+ # `nil` is returned if the two values are incomparable.
42
+ #
43
+ def <=>(other)
44
+ logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
45
+ if other.respond_to?(:to_str)
46
+ to_str <=> other.to_str
47
+ elsif other.respond_to?(:coerce)
48
+ return nil unless (lhs, rhs = other.coerce(self))
49
+
50
+ lhs <=> rhs
51
+ end
52
+ end
53
+
54
+ #
55
+ # Type Coercion
56
+ #
57
+ # Coerce object to a StringType
58
+ #
59
+ # @param [String] other object to coerce to a
60
+ # DateTimeType
61
+ #
62
+ # @return [[StringType, StringType], nil]
63
+ #
64
+ def coerce(other)
65
+ logger.trace("Coercing #{self} as a request from #{other.class}")
66
+ return [String.new(other.to_str), self] if other.respond_to?(:to_str)
67
+ end
68
+
69
+ # any method that exists on String gets forwarded to to_s
70
+ delegate (String.instance_methods - instance_methods + %w[=~ inspect]) => :to_s
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # @!parse StringType = OpenHAB::Core::Types::StringType