openhab-scripting 4.1.4 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openhab/core/entity_lookup.rb +1 -57
- data/lib/openhab/dsl/dsl.rb +6 -12
- data/lib/openhab/dsl/group.rb +1 -5
- data/lib/openhab/dsl/items/comparable_item.rb +49 -0
- data/lib/openhab/dsl/items/contact_item.rb +41 -0
- data/lib/openhab/dsl/items/date_time_item.rb +64 -0
- data/lib/openhab/dsl/items/dimmer_item.rb +59 -0
- data/lib/openhab/dsl/items/generic_item.rb +197 -0
- data/lib/openhab/dsl/items/group_item.rb +56 -92
- data/lib/openhab/dsl/items/image_item.rb +5 -41
- data/lib/openhab/dsl/items/item_registry.rb +49 -0
- data/lib/openhab/dsl/items/items.rb +71 -35
- data/lib/openhab/dsl/items/metadata.rb +325 -0
- data/lib/openhab/dsl/items/number_item.rb +6 -312
- data/lib/openhab/dsl/items/numeric_item.rb +66 -0
- data/lib/openhab/dsl/items/persistence.rb +122 -0
- data/lib/openhab/dsl/items/player_item.rb +49 -40
- data/lib/openhab/dsl/items/rollershutter_item.rb +25 -77
- data/lib/openhab/dsl/items/string_item.rb +16 -58
- data/lib/openhab/dsl/items/switch_item.rb +62 -0
- data/lib/openhab/dsl/lazy_array.rb +8 -6
- data/lib/openhab/dsl/monkey_patch/events/events.rb +2 -2
- data/lib/openhab/dsl/monkey_patch/events/item_command.rb +67 -24
- data/lib/openhab/dsl/monkey_patch/events/item_event.rb +5 -5
- data/lib/openhab/dsl/monkey_patch/events/item_state.rb +10 -11
- data/lib/openhab/dsl/monkey_patch/events/item_state_changed.rb +10 -11
- data/lib/openhab/dsl/monkey_patch/ruby/number.rb +25 -2
- data/lib/openhab/dsl/monkey_patch/ruby/ruby.rb +0 -3
- data/lib/openhab/dsl/monkey_patch/ruby/string.rb +24 -24
- data/lib/openhab/dsl/states.rb +1 -1
- data/lib/openhab/dsl/time_of_day.rb +3 -5
- data/lib/openhab/dsl/types/comparable_type.rb +21 -0
- data/lib/openhab/dsl/types/date_time_type.rb +334 -0
- data/lib/openhab/dsl/types/decimal_type.rb +187 -0
- data/lib/openhab/dsl/types/increase_decrease_type.rb +23 -0
- data/lib/openhab/dsl/types/next_previous_type.rb +23 -0
- data/lib/openhab/dsl/types/numeric_type.rb +39 -0
- data/lib/openhab/dsl/types/on_off_type.rb +29 -0
- data/lib/openhab/dsl/types/open_closed_type.rb +29 -0
- data/lib/openhab/dsl/types/percent_type.rb +68 -0
- data/lib/openhab/dsl/types/play_pause_type.rb +27 -0
- data/lib/openhab/dsl/types/quantity_type.rb +275 -0
- data/lib/openhab/dsl/types/refresh_type.rb +18 -0
- data/lib/openhab/dsl/types/rewind_fastforward_type.rb +33 -0
- data/lib/openhab/dsl/types/stop_move_type.rb +23 -0
- data/lib/openhab/dsl/types/string_type.rb +88 -0
- data/lib/openhab/dsl/types/type.rb +72 -0
- data/lib/openhab/dsl/types/types.rb +77 -0
- data/lib/openhab/dsl/types/un_def_type.rb +22 -0
- data/lib/openhab/dsl/types/up_down_type.rb +32 -0
- data/lib/openhab/dsl/units.rb +11 -6
- data/lib/openhab/version.rb +1 -1
- data/lib/openhab.rb +0 -1
- metadata +31 -28
- data/lib/openhab/dsl/items/datetime_item.rb +0 -75
- data/lib/openhab/dsl/items/item_command.rb +0 -90
- data/lib/openhab/dsl/items/item_delegate.rb +0 -125
- data/lib/openhab/dsl/monkey_patch/items/contact_item.rb +0 -51
- data/lib/openhab/dsl/monkey_patch/items/dimmer_item.rb +0 -140
- data/lib/openhab/dsl/monkey_patch/items/items.rb +0 -142
- data/lib/openhab/dsl/monkey_patch/items/metadata.rb +0 -328
- data/lib/openhab/dsl/monkey_patch/items/persistence.rb +0 -123
- data/lib/openhab/dsl/monkey_patch/items/switch_item.rb +0 -71
- data/lib/openhab/dsl/monkey_patch/ruby/range.rb +0 -47
- data/lib/openhab/dsl/monkey_patch/ruby/time.rb +0 -32
- data/lib/openhab/dsl/monkey_patch/types/decimal_type.rb +0 -97
- data/lib/openhab/dsl/monkey_patch/types/increase_decrease_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/next_previous_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/on_off_type.rb +0 -79
- data/lib/openhab/dsl/monkey_patch/types/open_closed_type.rb +0 -71
- data/lib/openhab/dsl/monkey_patch/types/percent_type.rb +0 -77
- data/lib/openhab/dsl/monkey_patch/types/play_pause_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/quantity_type.rb +0 -69
- data/lib/openhab/dsl/monkey_patch/types/refresh_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/rewind_fastforward_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/stop_move_type.rb +0 -23
- data/lib/openhab/dsl/monkey_patch/types/types.rb +0 -15
- data/lib/openhab/dsl/monkey_patch/types/up_down_type.rb +0 -72
- data/lib/openhab/dsl/types/datetime.rb +0 -338
- data/lib/openhab/dsl/types/quantity.rb +0 -300
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.library.types.PercentType
|
7
|
+
|
8
|
+
# global alias
|
9
|
+
::PercentType = PercentType
|
10
|
+
|
11
|
+
# Adds methods to core OpenHAB PercentType to make it more natural in Ruby
|
12
|
+
class PercentType < DecimalType
|
13
|
+
# remove the JRuby default == so that we can inherit the Ruby method
|
14
|
+
remove_method :==
|
15
|
+
|
16
|
+
#
|
17
|
+
# Check if +ON+
|
18
|
+
#
|
19
|
+
# Note that +ON+ is defined as any value besides 0%.
|
20
|
+
#
|
21
|
+
# @return [Boolean]
|
22
|
+
#
|
23
|
+
def on?
|
24
|
+
as(OnOffType).on?
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Check if +OFF+
|
29
|
+
#
|
30
|
+
# Note that +OFF+ is defined as 0% exactly.
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
#
|
34
|
+
def off?
|
35
|
+
as(OnOffType).off?
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Check if +UP+
|
40
|
+
#
|
41
|
+
# Note that +UP+ is defined as 0% exactly.
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
#
|
45
|
+
def up?
|
46
|
+
!!as(UpDownType)&.up?
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Check if +DOWN+
|
51
|
+
#
|
52
|
+
# Note that +DOWN+ is defined as 100% exactly.
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
#
|
56
|
+
def down?
|
57
|
+
!!as(UpDownType)&.down?
|
58
|
+
end
|
59
|
+
|
60
|
+
# include the %
|
61
|
+
# @!visibility private
|
62
|
+
def to_s
|
63
|
+
"#{to_string}%"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.library.types.PlayPauseType
|
7
|
+
|
8
|
+
# Adds methods to core OpenHAB PlayPauseType to make it more
|
9
|
+
# natural in Ruby
|
10
|
+
class PlayPauseType # rubocop:disable Lint/EmptyClass
|
11
|
+
# @!parse include Type
|
12
|
+
|
13
|
+
# @!method playing?
|
14
|
+
# Check if == +PLAY+
|
15
|
+
# @return [Boolean]
|
16
|
+
|
17
|
+
# @!parse alias play? playing?
|
18
|
+
|
19
|
+
# @!method paused?
|
20
|
+
# Check if == +PAUSE+
|
21
|
+
# @return [Boolean]
|
22
|
+
|
23
|
+
# @!parse alias pause? paused?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'numeric_type'
|
4
|
+
|
5
|
+
module OpenHAB
|
6
|
+
module DSL
|
7
|
+
module Types
|
8
|
+
java_import org.openhab.core.library.types.QuantityType
|
9
|
+
|
10
|
+
# global alias
|
11
|
+
::QuantityType = QuantityType
|
12
|
+
|
13
|
+
# @deprecated
|
14
|
+
# Backwards-compatible alias
|
15
|
+
Quantity = QuantityType
|
16
|
+
|
17
|
+
# Adds methods to core OpenHAB QuantityType to make it more natural in Ruby
|
18
|
+
class QuantityType # rubocop:disable Metrics/ClassLength
|
19
|
+
# @!parse include Type
|
20
|
+
include NumericType
|
21
|
+
|
22
|
+
# private alias
|
23
|
+
ONE = org.openhab.core.library.unit.Units::ONE
|
24
|
+
private_constant :ONE
|
25
|
+
|
26
|
+
#
|
27
|
+
# Convert this quantity into a another unit
|
28
|
+
#
|
29
|
+
# @param [Object] other String or Unit to convert to
|
30
|
+
#
|
31
|
+
# @return [QuantityType] This quantity converted to another unit
|
32
|
+
#
|
33
|
+
def |(other)
|
34
|
+
other = org.openhab.core.types.util.UnitUtils.parse_unit(other) if other.is_a?(String)
|
35
|
+
|
36
|
+
to_unit(other)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Comparison
|
41
|
+
#
|
42
|
+
# @param [NumericType, Items::NumericItem, Numeric, String]
|
43
|
+
# other object to compare to
|
44
|
+
#
|
45
|
+
# @return [Integer, nil] -1, 0, +1 depending on whether +other+ is
|
46
|
+
# less than, equal to, or greater than self
|
47
|
+
#
|
48
|
+
# nil is returned if the two values are incomparable
|
49
|
+
#
|
50
|
+
def <=>(other) # rubocop:disable Metrics
|
51
|
+
logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
|
52
|
+
if other.is_a?(self.class)
|
53
|
+
compare_to(other)
|
54
|
+
elsif other.is_a?(Items::NumericItem) ||
|
55
|
+
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(NumericItem))
|
56
|
+
return nil unless other.state?
|
57
|
+
|
58
|
+
self <=> other.state
|
59
|
+
elsif other.respond_to?(:to_str)
|
60
|
+
compare_to(QuantityType.new(other.to_str))
|
61
|
+
elsif other.respond_to?(:to_d)
|
62
|
+
compare_to(QuantityType.new(other.to_d.to_java, Units.unit || unit))
|
63
|
+
elsif other.respond_to?(:coerce)
|
64
|
+
lhs, rhs = other.coerce(self)
|
65
|
+
lhs <=> rhs
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Type Coercion
|
71
|
+
#
|
72
|
+
# Coerce object to a QuantityType
|
73
|
+
#
|
74
|
+
# @param [Items::NumericItem, Numeric, Type, String] other object to
|
75
|
+
# coerce to a {QuantityType}
|
76
|
+
#
|
77
|
+
# if +other+ is a {Type}, +self+ will instead be coerced
|
78
|
+
# to that type to accomodate comparison with things such as {OnOffType}
|
79
|
+
#
|
80
|
+
# @return [[QuantityType, QuantityType]]
|
81
|
+
def coerce(other) # rubocop:disable Metrics
|
82
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
83
|
+
if other.is_a?(Items::NumericItem) ||
|
84
|
+
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
85
|
+
raise TypeError, "can't convert #{UnDefType} into #{self.class}" unless other.state?
|
86
|
+
|
87
|
+
[other.state, self]
|
88
|
+
elsif other.is_a?(Type)
|
89
|
+
[other, as(other.class)]
|
90
|
+
elsif other.respond_to?(:to_d)
|
91
|
+
[QuantityType.new(other.to_d.to_java, ONE), self]
|
92
|
+
elsif other.is_a?(String)
|
93
|
+
[QuantityType.new(other), self]
|
94
|
+
else
|
95
|
+
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# arithmetic operators
|
100
|
+
alias -@ negate
|
101
|
+
|
102
|
+
{
|
103
|
+
:add => :+,
|
104
|
+
:subtract => :-
|
105
|
+
}.each do |java_op, ruby_op|
|
106
|
+
convert = 'self.class.new(other, Units.unit || unit)'
|
107
|
+
|
108
|
+
class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
|
109
|
+
# def +(other)
|
110
|
+
# logger.trace("#{self} + #{other} (#{other.class})")
|
111
|
+
# if other.is_a?(Items::NumericItem) ||
|
112
|
+
# (other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
113
|
+
# self + other.state
|
114
|
+
# elsif other.is_a?(QuantityType)
|
115
|
+
# add_quantity(other)
|
116
|
+
# elsif other.is_a?(DecimalType)
|
117
|
+
# other = other.to_big_decimal
|
118
|
+
# add_quantity(self.class.new(other, Units.unit || unit))
|
119
|
+
# elsif other.is_a?(java.math.BigDecimal)
|
120
|
+
# add_quantity(self.class.new(other, Units.unit || unit))
|
121
|
+
# elsif other.respond_to?(:to_str)
|
122
|
+
# self + self.class.new(other)
|
123
|
+
# elsif other.respond_to?(:to_d)
|
124
|
+
# other = other.to_d.to_java
|
125
|
+
# add_quantity(self.class.new(other, Units.unit || unit))
|
126
|
+
# elsif other.respond_to?(:coerce)
|
127
|
+
# lhs, rhs = other.coerce(to_d)
|
128
|
+
# lhs = rhs
|
129
|
+
# else
|
130
|
+
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
<<~RUBY, __FILE__, __LINE__ + 1
|
134
|
+
def #{ruby_op}(other)
|
135
|
+
logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
|
136
|
+
if other.is_a?(Items::NumericItem) ||
|
137
|
+
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
138
|
+
self #{ruby_op} other.state
|
139
|
+
elsif other.is_a?(QuantityType)
|
140
|
+
#{java_op}_quantity(other)
|
141
|
+
elsif other.is_a?(DecimalType)
|
142
|
+
other = other.to_big_decimal
|
143
|
+
#{java_op}_quantity(#{convert})
|
144
|
+
elsif other.is_a?(java.math.BigDecimal)
|
145
|
+
#{java_op}_quantity(#{convert})
|
146
|
+
elsif other.respond_to?(:to_str)
|
147
|
+
self #{ruby_op} self.class.new(other)
|
148
|
+
elsif other.respond_to?(:to_d)
|
149
|
+
other = other.to_d.to_java
|
150
|
+
#{java_op}_quantity(#{convert})
|
151
|
+
elsif other.respond_to?(:coerce)
|
152
|
+
lhs, rhs = other.coerce(to_d)
|
153
|
+
lhs #{ruby_op} rhs
|
154
|
+
else
|
155
|
+
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
RUBY
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
{
|
163
|
+
:multiply => :*,
|
164
|
+
:divide => :/
|
165
|
+
}.each do |java_op, ruby_op|
|
166
|
+
class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
|
167
|
+
# def *(other)
|
168
|
+
# logger.trace("#{self} * #{other} (#{other.class})")
|
169
|
+
# if other.is_a?(Items::NumericItem) ||
|
170
|
+
# (other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
171
|
+
# self * other.state
|
172
|
+
# elsif other.is_a?(QuantityType)
|
173
|
+
# multiply_quantity(other)
|
174
|
+
# elsif other.is_a?(DecimalType)
|
175
|
+
# multiply(other.to_big_decimal)
|
176
|
+
# elsif other.is_a?(java.math.BigDecimal)
|
177
|
+
# multiply(other)
|
178
|
+
# elsif other.respond_to?(:to_str)
|
179
|
+
# self * self.class.new(other)
|
180
|
+
# elsif other.respond_to?(:to_d)
|
181
|
+
# multiply(other.to_d.to_java)
|
182
|
+
# elsif other.respond_to?(:coerce)
|
183
|
+
# lhs, rhs = other.coerce(to_d)
|
184
|
+
# lhs * rhs
|
185
|
+
# else
|
186
|
+
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
187
|
+
# end
|
188
|
+
# end
|
189
|
+
<<~RUBY, __FILE__, __LINE__ + 1
|
190
|
+
def #{ruby_op}(other)
|
191
|
+
logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
|
192
|
+
if other.is_a?(Items::NumericItem) ||
|
193
|
+
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
194
|
+
self #{ruby_op} other.state
|
195
|
+
elsif other.is_a?(QuantityType)
|
196
|
+
#{java_op}_quantity(other)
|
197
|
+
elsif other.is_a?(DecimalType)
|
198
|
+
#{java_op}(other.to_big_decimal)
|
199
|
+
elsif other.is_a?(java.math.BigDecimal)
|
200
|
+
#{java_op}(other)
|
201
|
+
elsif other.respond_to?(:to_str)
|
202
|
+
self #{ruby_op} self.class.new(other)
|
203
|
+
elsif other.respond_to?(:to_d)
|
204
|
+
#{java_op}(other.to_d.to_java)
|
205
|
+
elsif other.respond_to?(:coerce)
|
206
|
+
lhs, rhs = other.coerce(to_d)
|
207
|
+
lhs #{ruby_op} rhs
|
208
|
+
else
|
209
|
+
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
RUBY
|
213
|
+
)
|
214
|
+
end
|
215
|
+
|
216
|
+
# if it's a dimensionless quantity, change the unit to match other_unit
|
217
|
+
# @!visibility private
|
218
|
+
def unitize(other_unit = unit)
|
219
|
+
# prefer converting to the thread-specified unit if there is one
|
220
|
+
other_unit = Units.unit || other_unit
|
221
|
+
logger.trace("Converting #{self} to #{other_unit}")
|
222
|
+
|
223
|
+
case unit
|
224
|
+
when ONE
|
225
|
+
QuantityType.new(to_big_decimal, other_unit)
|
226
|
+
when other_unit
|
227
|
+
self
|
228
|
+
else
|
229
|
+
to_unit(other_unit)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# if unit is +ONE+, return a plain Java BigDecimal
|
234
|
+
# @!visibility private
|
235
|
+
def deunitize
|
236
|
+
return to_big_decimal if unit == ONE
|
237
|
+
|
238
|
+
self
|
239
|
+
end
|
240
|
+
|
241
|
+
private
|
242
|
+
|
243
|
+
# do addition directly against a QuantityType while ensuring we unitize
|
244
|
+
# both sides
|
245
|
+
def add_quantity(other)
|
246
|
+
unitize(other.unit).add(other.unitize(unit))
|
247
|
+
end
|
248
|
+
|
249
|
+
# do subtraction directly against a QuantityType while ensuring we
|
250
|
+
# unitize both sides
|
251
|
+
def subtract_quantity(other)
|
252
|
+
unitize(other.unit).subtract(other.unitize(unit))
|
253
|
+
end
|
254
|
+
|
255
|
+
# do multiplication directly against a QuantityType while ensuring
|
256
|
+
# we deunitize both sides, and also invert the operation if one side
|
257
|
+
# isn't actually a unit
|
258
|
+
def multiply_quantity(other)
|
259
|
+
lhs = deunitize
|
260
|
+
rhs = other.deunitize
|
261
|
+
# reverse the arguments if it's multiplication and the LHS isn't a QuantityType
|
262
|
+
lhs, rhs = rhs, lhs if lhs.is_a?(java.math.BigDecimal)
|
263
|
+
# what a waste... using a QuantityType to multiply two dimensionless quantities
|
264
|
+
# have to make sure lhs is still a QuantityType in order to return a new
|
265
|
+
# QuantityType that's still dimensionless
|
266
|
+
lhs = other if lhs.is_a?(java.math.BigDecimal)
|
267
|
+
|
268
|
+
lhs.multiply(rhs)
|
269
|
+
end
|
270
|
+
|
271
|
+
alias divide_quantity divide
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.types.RefreshType
|
7
|
+
|
8
|
+
# Adds methods to core OpenHAB RefreshType to make it more natural in Ruby
|
9
|
+
class RefreshType # rubocop:disable Lint/EmptyClass
|
10
|
+
# @!parse include Type
|
11
|
+
|
12
|
+
# @!method refresh?
|
13
|
+
# Check if == +REFRESH+
|
14
|
+
# @return [Boolean]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.library.types.RewindFastforwardType
|
7
|
+
|
8
|
+
# Adds methods to core OpenHAB RewindFastforwardType to make it more
|
9
|
+
# natural in Ruby
|
10
|
+
class RewindFastforwardType # rubocop:disable Lint/EmptyClass
|
11
|
+
# @!parse include Type
|
12
|
+
|
13
|
+
# @!method rewinding?
|
14
|
+
# Check if == +REWIND+
|
15
|
+
# @return [Boolean]
|
16
|
+
|
17
|
+
# @!parse alias rewind? rewinding?
|
18
|
+
|
19
|
+
# @!method fast_forwarding?
|
20
|
+
# Check if == +FASTFORWARD+
|
21
|
+
# @return [Boolean]
|
22
|
+
|
23
|
+
# @!parse alias fast_forward? fast_forwarding?
|
24
|
+
|
25
|
+
# @deprecated
|
26
|
+
# @!parse alias fastforward? fast_forwarding?
|
27
|
+
|
28
|
+
# @deprecated
|
29
|
+
# @!parse alias fastforwarding? fast_forwarding?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.library.types.StopMoveType
|
7
|
+
|
8
|
+
# Adds methods to core OpenHAB StopMoveType to make it more
|
9
|
+
# natural in Ruby
|
10
|
+
class StopMoveType # rubocop:disable Lint/EmptyClass
|
11
|
+
# @!parse include Type
|
12
|
+
|
13
|
+
# @!method stop?
|
14
|
+
# Check if == +STOP+
|
15
|
+
# @return [Boolean]
|
16
|
+
|
17
|
+
# @!method move?
|
18
|
+
# Check if == +MOVE+
|
19
|
+
# @return [Boolean]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require_relative 'comparable_type'
|
6
|
+
|
7
|
+
module OpenHAB
|
8
|
+
module DSL
|
9
|
+
module Types
|
10
|
+
java_import org.openhab.core.library.types.StringType
|
11
|
+
|
12
|
+
#
|
13
|
+
# Add methods to core OpenHAB StringType to make it behave as a Ruby
|
14
|
+
# String object
|
15
|
+
#
|
16
|
+
class StringType
|
17
|
+
# @!parse include Type
|
18
|
+
|
19
|
+
extend Forwardable
|
20
|
+
include Comparable
|
21
|
+
include ComparableType
|
22
|
+
|
23
|
+
#
|
24
|
+
# Check equality without type conversion
|
25
|
+
#
|
26
|
+
# @return [Boolean] if the same value is represented, without type
|
27
|
+
# conversion
|
28
|
+
def eql?(other)
|
29
|
+
return false unless other.instance_of?(self.class)
|
30
|
+
|
31
|
+
to_s.compare_to(other.to_s).zero?
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Comparison
|
36
|
+
#
|
37
|
+
# @param [StringType, Items::StringItem, String]
|
38
|
+
# other object to compare to
|
39
|
+
#
|
40
|
+
# @return [Integer, nil] -1, 0, +1 depending on whether +other+ is
|
41
|
+
# less than, equal to, or greater than self
|
42
|
+
#
|
43
|
+
# nil is returned if the two values are incomparable
|
44
|
+
#
|
45
|
+
def <=>(other) # rubocop:disable Metrics
|
46
|
+
logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
|
47
|
+
if other.is_a?(Items::StringItem) ||
|
48
|
+
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(StringItem))
|
49
|
+
return nil unless other.state?
|
50
|
+
|
51
|
+
self <=> other.state
|
52
|
+
elsif other.respond_to?(:to_str)
|
53
|
+
to_str <=> other.to_str
|
54
|
+
elsif other.respond_to?(:coerce)
|
55
|
+
lhs, rhs = other.coerce(self)
|
56
|
+
lhs <=> rhs
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Type Coercion
|
62
|
+
#
|
63
|
+
# Coerce object to a StringType
|
64
|
+
#
|
65
|
+
# @param [Items::StringItem, String] other object to coerce to a
|
66
|
+
# DateTimeType
|
67
|
+
#
|
68
|
+
# @return [[StringType, StringType]]
|
69
|
+
#
|
70
|
+
def coerce(other)
|
71
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
72
|
+
if other.is_a?(Items::StringItem)
|
73
|
+
raise TypeError, "can't convert #{other.raw_state} into #{self.class}" unless other.state?
|
74
|
+
|
75
|
+
[other.state, self]
|
76
|
+
elsif other.respond_to?(:to_str)
|
77
|
+
[String.new(other.to_str), self]
|
78
|
+
else
|
79
|
+
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# any method that exists on String gets forwarded to to_s
|
84
|
+
delegate (String.instance_methods - instance_methods) => :to_s
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
module Types
|
6
|
+
java_import org.openhab.core.types.Type
|
7
|
+
|
8
|
+
#
|
9
|
+
# Add basic type conversion and comparison to all core OpenHAB types
|
10
|
+
#
|
11
|
+
module Type
|
12
|
+
# can't alias because to_s doesn't exist on Type
|
13
|
+
# @!visibility private
|
14
|
+
def inspect
|
15
|
+
to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Type Coercion
|
20
|
+
#
|
21
|
+
# Coerce object to the same Type
|
22
|
+
#
|
23
|
+
# @param [Type] other object to coerce to the same
|
24
|
+
# Type as this one
|
25
|
+
#
|
26
|
+
# @return [[Type, Type]]
|
27
|
+
#
|
28
|
+
def coerce(other)
|
29
|
+
logger.trace("Coercing #{self} (#{self.class}) as a request from #{other.class}")
|
30
|
+
return [other.as(self.class), self] if other.is_a?(Type)
|
31
|
+
|
32
|
+
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Check equality without type conversion
|
37
|
+
#
|
38
|
+
# @return [Boolean] if the same value is represented, without type
|
39
|
+
# conversion
|
40
|
+
def eql?(other)
|
41
|
+
return false unless other.instance_of?(self.class)
|
42
|
+
|
43
|
+
equals(other)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Check equality, including type conversion
|
48
|
+
#
|
49
|
+
# @return [Boolean] if the same value is represented, including
|
50
|
+
# type conversions
|
51
|
+
#
|
52
|
+
def ==(other)
|
53
|
+
return true if equal?(other)
|
54
|
+
|
55
|
+
# i.e. ON == OFF, REFRESH == ON, ON == REFRESH
|
56
|
+
# (RefreshType isn't really coercible)
|
57
|
+
return equals(other) if other.instance_of?(self.class) || is_a?(RefreshType) || other.is_a?(RefreshType)
|
58
|
+
|
59
|
+
# i.e. ON == DimmerItem (also case statements)
|
60
|
+
return self == other.raw_state if other.is_a?(Items::GenericItem)
|
61
|
+
|
62
|
+
if other.respond_to?(:coerce)
|
63
|
+
lhs, rhs = other.coerce(self)
|
64
|
+
return lhs == rhs
|
65
|
+
end
|
66
|
+
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'type'
|
4
|
+
|
5
|
+
require_relative 'date_time_type'
|
6
|
+
require_relative 'decimal_type'
|
7
|
+
require_relative 'increase_decrease_type'
|
8
|
+
require_relative 'next_previous_type'
|
9
|
+
require_relative 'open_closed_type'
|
10
|
+
require_relative 'on_off_type'
|
11
|
+
require_relative 'percent_type'
|
12
|
+
require_relative 'play_pause_type'
|
13
|
+
require_relative 'quantity_type'
|
14
|
+
require_relative 'refresh_type'
|
15
|
+
require_relative 'rewind_fastforward_type'
|
16
|
+
require_relative 'stop_move_type'
|
17
|
+
require_relative 'string_type'
|
18
|
+
require_relative 'up_down_type'
|
19
|
+
require_relative 'un_def_type'
|
20
|
+
|
21
|
+
module OpenHAB
|
22
|
+
module DSL
|
23
|
+
#
|
24
|
+
# Contains all OpenHAB *Type classes, as well as associated support
|
25
|
+
# modules
|
26
|
+
#
|
27
|
+
module Types
|
28
|
+
# Hash taking a Enum value, and returning two symbols of
|
29
|
+
# predicates to be defined for it. the first is the "command" form,
|
30
|
+
# which should be defined on ItemCommandEvent, and on the Type itself.
|
31
|
+
# the second is "state" form, which should be defined on the applicable
|
32
|
+
# Item, and on the Type itself.
|
33
|
+
# @!visibility private
|
34
|
+
PREDICATE_ALIASES = Hash.new { |_h, k| [:"#{k.downcase}?"] * 2 }
|
35
|
+
.merge({
|
36
|
+
'PLAY' => %i[play? playing?],
|
37
|
+
'PAUSE' => %i[pause? paused?],
|
38
|
+
'REWIND' => %i[rewind? rewinding?],
|
39
|
+
'FASTFORWARD' => %i[fast_forward? fast_forwarding?]
|
40
|
+
}).freeze
|
41
|
+
|
42
|
+
# Hash taking a Enum value, and returning an array of symbols
|
43
|
+
# of the command to define for it
|
44
|
+
# @!visibility private
|
45
|
+
COMMAND_ALIASES = Hash.new { |_h, k| k.downcase.to_sym }
|
46
|
+
.merge({
|
47
|
+
'FASTFORWARD' => :fast_forward
|
48
|
+
}).freeze
|
49
|
+
|
50
|
+
constants.map { |c| const_get(c) }
|
51
|
+
.grep(Module)
|
52
|
+
.select { |k| k < java.lang.Enum }
|
53
|
+
.each do |klass|
|
54
|
+
# make sure == from Type is inherited
|
55
|
+
klass.remove_method(:==)
|
56
|
+
|
57
|
+
# dynamically define predicate methods
|
58
|
+
klass.values.each do |value| # rubocop:disable Style/HashEachMethods this isn't a Ruby hash
|
59
|
+
# include all the aliases that we define for items both command and
|
60
|
+
# state aliases (since types can be interrogated as an incoming
|
61
|
+
# command, or as the state of an item)
|
62
|
+
command = :"#{COMMAND_ALIASES[value.to_s]}?"
|
63
|
+
states = PREDICATE_ALIASES[value.to_s]
|
64
|
+
|
65
|
+
([command] | states).each do |method|
|
66
|
+
OpenHAB::Core.logger.trace("Defining #{klass}##{method} for #{value}")
|
67
|
+
klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
68
|
+
def #{method} # def on?
|
69
|
+
self == #{value} # self == ON
|
70
|
+
end # end
|
71
|
+
RUBY
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|