openhab-scripting 4.1.4 → 4.5.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/actions.rb +2 -3
- data/lib/openhab/dsl/dsl.rb +8 -12
- data/lib/openhab/dsl/group.rb +1 -5
- data/lib/openhab/dsl/items/color_item.rb +60 -0
- 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/ensure.rb +93 -0
- data/lib/openhab/dsl/items/generic_item.rb +174 -0
- data/lib/openhab/dsl/items/group_item.rb +121 -89
- data/lib/openhab/dsl/items/image_item.rb +5 -41
- data/lib/openhab/dsl/items/item_equality.rb +36 -0
- data/lib/openhab/dsl/items/item_registry.rb +49 -0
- data/lib/openhab/dsl/items/items.rb +81 -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 +68 -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/rules/terse.rb +24 -0
- 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/hsb_type.rb +201 -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 +70 -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 +78 -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 +36 -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
|
@@ -1,323 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
4
|
-
require 'forwardable'
|
|
5
|
-
require 'java'
|
|
6
|
-
require 'openhab/dsl/types/quantity'
|
|
7
|
-
require 'openhab/dsl/items/item_delegate'
|
|
3
|
+
require 'openhab/dsl/items/numeric_item'
|
|
8
4
|
|
|
9
5
|
module OpenHAB
|
|
10
6
|
module DSL
|
|
11
7
|
module Items
|
|
12
|
-
|
|
13
|
-
# Delegation to OpenHAB Number Item
|
|
14
|
-
#
|
|
15
|
-
# rubocop: disable Metrics/ClassLength
|
|
16
|
-
# Disabled because this class has a single responsibility, there does not appear a logical
|
|
17
|
-
# way of breaking it up into multiple classes
|
|
18
|
-
class NumberItem < Numeric
|
|
19
|
-
extend OpenHAB::DSL::Items::ItemDelegate
|
|
20
|
-
extend OpenHAB::DSL::Items::ItemCommand
|
|
8
|
+
java_import org.openhab.core.library.items.NumberItem
|
|
21
9
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
java_import org.openhab.core.types.util.UnitUtils
|
|
27
|
-
java_import org.openhab.core.library.unit.Units
|
|
28
|
-
|
|
29
|
-
item_type Java::OrgOpenhabCoreLibraryItems::NumberItem
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
# Create a new NumberItem
|
|
33
|
-
#
|
|
34
|
-
# @param [Java::Org::openhab::core::library::items::NumberItem] number_item OpenHAB number item to delegate to
|
|
35
|
-
#
|
|
36
|
-
def initialize(number_item)
|
|
37
|
-
@number_item = number_item
|
|
38
|
-
item_missing_delegate { @number_item }
|
|
39
|
-
super()
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
# Check if NumberItem is truthy? as per defined by library
|
|
44
|
-
#
|
|
45
|
-
# @return [Boolean] True if item is not in state UNDEF or NULL and value is not zero.
|
|
46
|
-
#
|
|
47
|
-
def truthy?
|
|
48
|
-
@number_item.state? && @number_item.state != DecimalType::ZERO
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
# Coerce objects into a NumberItem
|
|
53
|
-
#
|
|
54
|
-
# @param [Object] other object to coerce to a NumberItem if possible
|
|
55
|
-
#
|
|
56
|
-
# @return [Object] NumberItem, QuantityTypes, BigDecimal or nil depending on NumberItem configuration
|
|
57
|
-
# and/or supplied object
|
|
58
|
-
#
|
|
59
|
-
def coerce(other)
|
|
60
|
-
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
61
|
-
case other
|
|
62
|
-
when Quantity then coerce_from_quantity(other)
|
|
63
|
-
when Numeric then coerce_from_numeric(other)
|
|
64
|
-
else
|
|
65
|
-
logger.trace("#{self} cannot be coerced to #{other.class}")
|
|
66
|
-
nil
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
#
|
|
71
|
-
# Compare NumberItem to supplied object
|
|
72
|
-
#
|
|
73
|
-
# @param [Object] other object to compare to
|
|
74
|
-
#
|
|
75
|
-
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
|
76
|
-
# nil comparison to supplied object is not possible.
|
|
77
|
-
#
|
|
78
|
-
def <=>(other)
|
|
79
|
-
logger.trace("NumberItem #{self} <=> #{other} (#{other.class})")
|
|
80
|
-
case other
|
|
81
|
-
when NumberItem then number_item_compare(other)
|
|
82
|
-
when Numeric then numeric_compare(other)
|
|
83
|
-
when String then string_compare(other)
|
|
84
|
-
else state_compare(other)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
#
|
|
89
|
-
# Convert NumberItem to a Quantity
|
|
90
|
-
#
|
|
91
|
-
# @param [Object] other String or Unit representing an OpenHAB Unit
|
|
92
|
-
#
|
|
93
|
-
# @return [OpenHAB::DSL::Types::Quantity] NumberItem converted to supplied Unit
|
|
94
|
-
#
|
|
95
|
-
def |(other)
|
|
96
|
-
other = UnitUtils.parse_unit(other) if other.is_a? String
|
|
97
|
-
|
|
98
|
-
if dimension
|
|
99
|
-
to_qt | other
|
|
100
|
-
else
|
|
101
|
-
Quantity.new(QuantityType.new(to_d.to_java, other))
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
#
|
|
106
|
-
# Convert NumberItem to a Quantity
|
|
107
|
-
#
|
|
108
|
-
# @return [OpenHAB::DSL::Types::Quantity] NumberItem converted to a QuantityUnit
|
|
109
|
-
#
|
|
110
|
-
def to_qt
|
|
111
|
-
if dimension
|
|
112
|
-
Quantity.new(@number_item.get_state_as(QuantityType))
|
|
113
|
-
else
|
|
114
|
-
Quantity.new(QuantityType.new(to_d.to_java, Units::ONE))
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
#
|
|
119
|
-
# Converts the NumberItem to an Integer
|
|
120
|
-
#
|
|
121
|
-
# @return [Integer] NumberItem as an integer
|
|
122
|
-
#
|
|
123
|
-
def to_i
|
|
124
|
-
to_d&.to_i
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
#
|
|
128
|
-
# Converts the NumberItem to a float
|
|
129
|
-
#
|
|
130
|
-
# @return [Float] NumberItem as a float
|
|
131
|
-
#
|
|
132
|
-
def to_f
|
|
133
|
-
to_d&.to_f
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
# Converts the NumberItem to a BigDecimal
|
|
138
|
-
#
|
|
139
|
-
# @return [BigDecimal] NumberItem as a BigDecimal
|
|
140
|
-
#
|
|
141
|
-
def to_d
|
|
142
|
-
@number_item.state.to_big_decimal.to_d if @number_item.state.respond_to? :to_big_decimal
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
#
|
|
146
|
-
# Get the Dimension attached to the NumberItem
|
|
147
|
-
#
|
|
148
|
-
# @return [Java::org::openhab::core::library::types::QuantityType] dimension
|
|
149
|
-
#
|
|
150
|
-
def dimension
|
|
151
|
-
@number_item.dimension
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
%w[+ - * /].each do |operation|
|
|
155
|
-
define_method(operation) do |other|
|
|
156
|
-
logger.trace("Execution math operation '#{operation}' on #{inspect} with #{other.inspect}")
|
|
157
|
-
left_operand, right_operand = operands_for_operation(other)
|
|
158
|
-
left_operand.public_send(operation, right_operand)
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
private
|
|
163
|
-
|
|
164
|
-
#
|
|
165
|
-
# Compare if other responds to state
|
|
166
|
-
#
|
|
167
|
-
# @param [Object] other object to compare to
|
|
168
|
-
#
|
|
169
|
-
# @return [Integer] -1,0,1 depending on less than, equal to or greater than other
|
|
170
|
-
#
|
|
171
|
-
def state_compare(other)
|
|
172
|
-
other = other.state if other.respond_to? :state
|
|
173
|
-
@number_item.state <=> other
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
#
|
|
177
|
-
# Compare if other is a String
|
|
178
|
-
#
|
|
179
|
-
# @param [String] other object to compare to
|
|
180
|
-
#
|
|
181
|
-
# @return [Integer] -1,0,1,nil depending on less than, equal to or greater than other
|
|
182
|
-
# nil if this number item does not have a dimension
|
|
183
|
-
#
|
|
184
|
-
def string_compare(other)
|
|
185
|
-
@number_item.state <=> QuantityType.new(other) if dimension
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
#
|
|
189
|
-
# Compare if other is a Numeric
|
|
190
|
-
#
|
|
191
|
-
# @param [String] other to compare to
|
|
192
|
-
#
|
|
193
|
-
# @return [Integer] -1,0,1 depending on less than, equal to or greater than other
|
|
194
|
-
#
|
|
195
|
-
def numeric_compare(other)
|
|
196
|
-
@number_item.state.to_big_decimal.to_d <=> other.to_d
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
#
|
|
200
|
-
# Get the operands for any operation
|
|
201
|
-
#
|
|
202
|
-
# @param [Object] other object to convert to a compatible operand
|
|
203
|
-
#
|
|
204
|
-
# @return [Array[Object,Object]] of operands where the first value is the left operand
|
|
205
|
-
# and the second value is the right operand
|
|
206
|
-
#
|
|
207
|
-
def operands_for_operation(other)
|
|
208
|
-
case other
|
|
209
|
-
when NumberItem then number_item_operands(other)
|
|
210
|
-
when Numeric then [to_d, other.to_d]
|
|
211
|
-
when String then string_operands(other)
|
|
212
|
-
else
|
|
213
|
-
return other.coerce(to_d) if other.respond_to? :coerce
|
|
214
|
-
|
|
215
|
-
raise ArgumentError, "#{other.class} can't be coerced into a NumberItem"
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
#
|
|
220
|
-
# Get operands for an operation when the right operand is provided as a string
|
|
221
|
-
#
|
|
222
|
-
# @param [String] other right operand
|
|
223
|
-
#
|
|
224
|
-
# @return [Array[QuantityType,QuantiyType]] of operands where the first value is the left operand
|
|
225
|
-
# and the second value is the right operand
|
|
226
|
-
#
|
|
227
|
-
def string_operands(other)
|
|
228
|
-
return [to_qt, Quantity.new(other)] if dimension
|
|
229
|
-
|
|
230
|
-
raise ArgumentError, 'Strings are only valid operands if NumberItem is dimensions=ed.'
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
#
|
|
234
|
-
# Get operands for an operation when the right operand is provided is another number item
|
|
235
|
-
#
|
|
236
|
-
# @param [NumberItem] other right operand
|
|
237
|
-
#
|
|
238
|
-
# @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>] of operands depending on
|
|
239
|
-
# if the left or right operand has a dimensions
|
|
240
|
-
#
|
|
241
|
-
def number_item_operands(other)
|
|
242
|
-
if dimension || other.dimension
|
|
243
|
-
dimensioned_operands(other)
|
|
244
|
-
else
|
|
245
|
-
logger.trace("Both objects lack dimension, self='#{self}' other='#{other}'")
|
|
246
|
-
# If nothing has a dimension, just use BigDecimals
|
|
247
|
-
[to_d, other.to_d]
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
#
|
|
252
|
-
# Get operands for an operation when the left or right operand has a dimension
|
|
253
|
-
#
|
|
254
|
-
# @param [NumberItem] other right operand
|
|
255
|
-
#
|
|
256
|
-
# @return [Array<QuantityType,QuantityType>] of operands
|
|
257
|
-
#
|
|
258
|
-
def dimensioned_operands(other)
|
|
259
|
-
logger.trace("Dimensions self='#{dimension}' other='#{other.dimension}'")
|
|
260
|
-
if dimension
|
|
261
|
-
if other.dimension
|
|
262
|
-
# If both numbers have dimensions, do the math on the quantity types.
|
|
263
|
-
[to_qt, other.to_qt]
|
|
264
|
-
else
|
|
265
|
-
# If this number has dimension and the other does not,
|
|
266
|
-
# do math with this quantity type and the other as a big decimal
|
|
267
|
-
[to_qt, other]
|
|
268
|
-
end
|
|
269
|
-
else
|
|
270
|
-
# If this number has no dimension and the other does, convert this into a dimensionless quantity
|
|
271
|
-
[to_qt, other]
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
#
|
|
276
|
-
# Compare two number items, taking into account any dimensions
|
|
277
|
-
#
|
|
278
|
-
# @param [NumberItem] other number item
|
|
279
|
-
#
|
|
280
|
-
# @return [-1,0,1] depending on if other object is less than, equal to or greater than self
|
|
281
|
-
#
|
|
282
|
-
def number_item_compare(other)
|
|
283
|
-
if other.dimension
|
|
284
|
-
logger.trace('Other is dimensioned, converting self and other to QuantityTypes to compare')
|
|
285
|
-
to_qt <=> other.to_qt
|
|
286
|
-
else
|
|
287
|
-
@number_item.state <=> other.state
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
#
|
|
292
|
-
# Coerce from a numberic object depnding on dimension and state
|
|
293
|
-
#
|
|
294
|
-
# @param [Numeric] other numeric object to convert
|
|
295
|
-
#
|
|
296
|
-
# @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>,nil] depending on
|
|
297
|
-
# if this object has a dimension or state
|
|
298
|
-
#
|
|
299
|
-
def coerce_from_numeric(other)
|
|
300
|
-
if dimension
|
|
301
|
-
[Quantity.new(other), to_qt]
|
|
302
|
-
elsif @number_item.state?
|
|
303
|
-
[other.to_d, @number_item.state.to_big_decimal.to_d]
|
|
304
|
-
end
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
#
|
|
308
|
-
# Coerce when other is a quantity
|
|
309
|
-
#
|
|
310
|
-
# @param [QuantityType] other
|
|
311
|
-
#
|
|
312
|
-
# @return [Array<QuanityType,QuantityType] other and self as a quantity type
|
|
313
|
-
#
|
|
314
|
-
def coerce_from_quantity(other)
|
|
315
|
-
as_qt = to_qt
|
|
316
|
-
logger.trace("Converted #{self} to a Quantity #{as_qt}")
|
|
317
|
-
[other, as_qt]
|
|
318
|
-
end
|
|
10
|
+
# Adds methods to core OpenHAB NumberItem type to make it more natural in
|
|
11
|
+
# Ruby
|
|
12
|
+
class NumberItem < GenericItem
|
|
13
|
+
include NumericItem
|
|
319
14
|
end
|
|
320
15
|
end
|
|
321
16
|
end
|
|
322
17
|
end
|
|
323
|
-
# rubocop: enable Metrics/ClassLength
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
require_relative 'comparable_item'
|
|
6
|
+
require_relative 'item_equality'
|
|
7
|
+
|
|
8
|
+
module OpenHAB
|
|
9
|
+
module DSL
|
|
10
|
+
module Items
|
|
11
|
+
# Mixin for implementing type coercieon, equality, and arithmetic for
|
|
12
|
+
# number-like items
|
|
13
|
+
module NumericItem
|
|
14
|
+
include Comparable
|
|
15
|
+
include ComparableItem
|
|
16
|
+
|
|
17
|
+
# apply meta-programming methods to including class
|
|
18
|
+
def self.included(klass)
|
|
19
|
+
klass.prepend ItemEquality # make sure this is first
|
|
20
|
+
klass.extend Forwardable
|
|
21
|
+
klass.delegate %i[+ - * / % | positive? negative? to_d to_f to_i to_int zero?] => :state
|
|
22
|
+
# remove the JRuby default == so that we can inherit the Ruby method
|
|
23
|
+
klass.remove_method :==
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Check if NumericItem is truthy? as per defined by library
|
|
28
|
+
#
|
|
29
|
+
# @return [Boolean] True if item is not in state +UNDEF+ or +NULL+ and value is not zero.
|
|
30
|
+
#
|
|
31
|
+
def truthy?
|
|
32
|
+
state && !state.zero?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Type Coercion
|
|
37
|
+
#
|
|
38
|
+
# Coerce object to a NumericType
|
|
39
|
+
#
|
|
40
|
+
# @param [Types::NumericType, Numeric] other object to coerce to a
|
|
41
|
+
# DateTimeType
|
|
42
|
+
#
|
|
43
|
+
# @return [[Types::NumericType, Types::NumericType]]
|
|
44
|
+
#
|
|
45
|
+
def coerce(other)
|
|
46
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
47
|
+
return [other, nil] unless state?
|
|
48
|
+
return [other, state] if other.is_a?(Types::NumericType) || other.respond_to?(:to_d)
|
|
49
|
+
|
|
50
|
+
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# strip trailing zeros from commands
|
|
54
|
+
# @!visibility private
|
|
55
|
+
def format_type(command)
|
|
56
|
+
# DecimalType and PercentType we want to make sure we don't have extra zeros
|
|
57
|
+
if command.instance_of?(Types::DecimalType) || command.instance_of?(Types::PercentType)
|
|
58
|
+
return command.to_big_decimal.strip_trailing_zeros.to_plain_string
|
|
59
|
+
end
|
|
60
|
+
# BigDecimal types have trailing zeros stripped
|
|
61
|
+
return command.to_java.strip_trailing_zeros.to_plain_string if command.is_a?(BigDecimal)
|
|
62
|
+
|
|
63
|
+
super
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module DSL
|
|
5
|
+
module Items
|
|
6
|
+
#
|
|
7
|
+
# Persistence extension for Items
|
|
8
|
+
#
|
|
9
|
+
module Persistence
|
|
10
|
+
java_import Java::OrgOpenhabCoreTypesUtil::UnitUtils
|
|
11
|
+
|
|
12
|
+
# A wrapper for OpenHAB's HistoricItem that returns the state directly
|
|
13
|
+
class HistoricState < SimpleDelegator
|
|
14
|
+
attr_reader :timestamp, :state
|
|
15
|
+
|
|
16
|
+
def initialize(state, timestamp)
|
|
17
|
+
@state = state
|
|
18
|
+
@timestamp = timestamp
|
|
19
|
+
super(@state)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# All persistence methods that could return a QuantityType
|
|
24
|
+
QUANTITY_METHODS = %i[average_since
|
|
25
|
+
delta_since
|
|
26
|
+
deviation_since
|
|
27
|
+
sum_since
|
|
28
|
+
variance_since].freeze
|
|
29
|
+
|
|
30
|
+
# All persistence methods that require a timestamp
|
|
31
|
+
PERSISTENCE_METHODS = (QUANTITY_METHODS +
|
|
32
|
+
%i[changed_since
|
|
33
|
+
evolution_rate
|
|
34
|
+
historic_state
|
|
35
|
+
maximum_since
|
|
36
|
+
minimum_since
|
|
37
|
+
updated_since]).freeze
|
|
38
|
+
private_constant :QUANTITY_METHODS, :PERSISTENCE_METHODS
|
|
39
|
+
|
|
40
|
+
%i[persist last_update].each do |method|
|
|
41
|
+
define_method(method) do |service = nil|
|
|
42
|
+
service ||= persistence_service
|
|
43
|
+
PersistenceExtensions.public_send(method, self, service&.to_s)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Return the previous state of the item
|
|
49
|
+
#
|
|
50
|
+
# @param skip_equal [Boolean] if true, skips equal state values and
|
|
51
|
+
# searches the first state not equal the current state
|
|
52
|
+
# @param service [String] the name of the PersistenceService to use
|
|
53
|
+
#
|
|
54
|
+
# @return the previous state or nil if no previous state could be found,
|
|
55
|
+
# or if the default persistence service is not configured or
|
|
56
|
+
# does not refer to a valid service
|
|
57
|
+
#
|
|
58
|
+
def previous_state(service = nil, skip_equal: false)
|
|
59
|
+
service ||= persistence_service
|
|
60
|
+
result = PersistenceExtensions.previous_state(self, skip_equal, service&.to_s)
|
|
61
|
+
HistoricState.new(quantify(result.state), result.timestamp)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
PERSISTENCE_METHODS.each do |method|
|
|
65
|
+
define_method(method) do |timestamp, service = nil|
|
|
66
|
+
service ||= persistence_service
|
|
67
|
+
result = PersistenceExtensions.public_send(method, self, to_zdt(timestamp), service&.to_s)
|
|
68
|
+
if result.is_a? Java::OrgOpenhabCorePersistence::HistoricItem
|
|
69
|
+
return HistoricState.new(quantify(result.state), result.timestamp)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
QUANTITY_METHODS.include?(method) ? quantify(result) : result
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
# Convert timestamp to ZonedDateTime if it's a TemporalAmount
|
|
80
|
+
#
|
|
81
|
+
# @param [Object] timestamp to convert
|
|
82
|
+
#
|
|
83
|
+
# @return [ZonedDateTime]
|
|
84
|
+
#
|
|
85
|
+
def to_zdt(timestamp)
|
|
86
|
+
if timestamp.is_a? Java::JavaTimeTemporal::TemporalAmount
|
|
87
|
+
logger.trace("Converting #{timestamp} (#{timestamp.class}) to ZonedDateTime")
|
|
88
|
+
Java::JavaTime::ZonedDateTime.now.minus(timestamp)
|
|
89
|
+
else
|
|
90
|
+
timestamp
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Convert value to QuantityType if it is a DecimalType and a unit is defined
|
|
96
|
+
#
|
|
97
|
+
# @param [Object] value The value to convert
|
|
98
|
+
#
|
|
99
|
+
# @return [Object] QuantityType or the original value
|
|
100
|
+
#
|
|
101
|
+
def quantify(value)
|
|
102
|
+
if value.is_a?(Types::DecimalType) && state_description&.pattern
|
|
103
|
+
item_unit = UnitUtils.parse_unit(state_description.pattern)
|
|
104
|
+
logger.trace("Unitizing #{value} with unit #{item_unit}")
|
|
105
|
+
Types::QuantityType.new(value.to_big_decimal, item_unit)
|
|
106
|
+
else
|
|
107
|
+
value
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# Get the specified persistence service from the current thread local variable
|
|
113
|
+
#
|
|
114
|
+
# @return [Object] Persistence service name as String or Symbol, or nil if not set
|
|
115
|
+
#
|
|
116
|
+
def persistence_service
|
|
117
|
+
Thread.current.thread_variable_get(:persistence_service)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -1,48 +1,57 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'forwardable'
|
|
4
|
-
require 'java'
|
|
5
|
-
require 'openhab/dsl/items/item_command'
|
|
6
|
-
require 'openhab/dsl/items/item_delegate'
|
|
7
|
-
|
|
8
3
|
module OpenHAB
|
|
9
4
|
module DSL
|
|
10
5
|
module Items
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
6
|
+
java_import org.openhab.core.library.items.PlayerItem
|
|
7
|
+
|
|
8
|
+
# Adds methods to core OpenHAB NumberItem type to make it more natural in
|
|
9
|
+
# Ruby
|
|
10
|
+
class PlayerItem < GenericItem
|
|
11
|
+
remove_method :==
|
|
12
|
+
|
|
13
|
+
# @!method play?
|
|
14
|
+
# Check if the item state == +PLAYING+
|
|
15
|
+
# @return [Boolean]
|
|
16
|
+
|
|
17
|
+
# @deprecated
|
|
18
|
+
# @!parse alias play? playing?
|
|
19
|
+
|
|
20
|
+
# @!method paused?
|
|
21
|
+
# Check if the item state == +PAUSED+
|
|
22
|
+
# @return [Boolean]
|
|
23
|
+
|
|
24
|
+
# @!method rewinding?
|
|
25
|
+
# Check if the item state == +REWIND+
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
|
|
28
|
+
# @!method fast_forwarding?
|
|
29
|
+
# Check if the item state == +FASTFORWARD+
|
|
30
|
+
# @return [Boolean]
|
|
31
|
+
|
|
32
|
+
# @!method play
|
|
33
|
+
# Send the +PLAY+ command to the item
|
|
34
|
+
# @return [PlayerItem] +self+
|
|
35
|
+
|
|
36
|
+
# @!method pause
|
|
37
|
+
# Send the +PAUSE+ command to the item
|
|
38
|
+
# @return [PlayerItem] +self+
|
|
39
|
+
|
|
40
|
+
# @!method rewind
|
|
41
|
+
# Send the +REWIND+ command to the item
|
|
42
|
+
# @return [PlayerItem] +self+
|
|
43
|
+
|
|
44
|
+
# @!method fast_forward
|
|
45
|
+
# Send the +FASTFORWARD+ command to the item
|
|
46
|
+
# @return [PlayerItem] +self+
|
|
47
|
+
|
|
48
|
+
# @!method next
|
|
49
|
+
# Send the +NEXT+ command to the item
|
|
50
|
+
# @return [PlayerItem] +self+
|
|
51
|
+
|
|
52
|
+
# @!method previous
|
|
53
|
+
# Send the +PREVIOUS+ command to the item
|
|
54
|
+
# @return [PlayerItem] +self+
|
|
46
55
|
end
|
|
47
56
|
end
|
|
48
57
|
end
|