openhab-scripting 4.1.4 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|