openhab-scripting 2.14.1 → 2.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openhab.rb +3 -0
- data/lib/openhab/core/dsl.rb +4 -0
- data/lib/openhab/core/dsl/actions.rb +1 -1
- data/lib/openhab/core/dsl/entities.rb +41 -4
- data/lib/openhab/core/dsl/gems.rb +1 -1
- data/lib/openhab/core/dsl/group.rb +3 -1
- data/lib/openhab/core/dsl/items/items.rb +3 -1
- data/lib/openhab/core/dsl/items/number_item.rb +158 -52
- data/lib/openhab/core/dsl/items/string_item.rb +23 -3
- data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +20 -5
- data/lib/openhab/core/dsl/monkey_patch/items/items.rb +2 -0
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +66 -42
- data/lib/openhab/core/dsl/monkey_patch/items/persistence.rb +72 -0
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +2 -1
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +2 -1
- data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +1 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/string.rb +43 -0
- data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +41 -5
- data/lib/openhab/core/dsl/monkey_patch/types/quantity_type.rb +58 -0
- data/lib/openhab/core/dsl/monkey_patch/types/types.rb +1 -0
- data/lib/openhab/core/dsl/persistence.rb +27 -0
- data/lib/openhab/core/dsl/property.rb +15 -4
- data/lib/openhab/core/dsl/rule/automation_rule.rb +348 -0
- data/lib/openhab/core/dsl/rule/guard.rb +43 -6
- data/lib/openhab/core/dsl/rule/rule.rb +80 -367
- data/lib/openhab/core/dsl/rule/rule_config.rb +153 -0
- data/lib/openhab/core/dsl/rule/triggers/changed.rb +145 -0
- data/lib/openhab/core/dsl/rule/{channel.rb → triggers/channel.rb} +22 -8
- data/lib/openhab/core/dsl/rule/triggers/command.rb +106 -0
- data/lib/openhab/core/dsl/rule/{cron.rb → triggers/cron.rb} +36 -14
- data/lib/openhab/core/dsl/rule/triggers/trigger.rb +126 -0
- data/lib/openhab/core/dsl/rule/triggers/updated.rb +100 -0
- data/lib/openhab/core/dsl/time_of_day.rb +53 -25
- data/lib/openhab/core/dsl/timers.rb +2 -6
- data/lib/openhab/core/dsl/types/quantity.rb +106 -69
- data/lib/openhab/core/log.rb +3 -8
- data/lib/openhab/core/startup_delay.rb +1 -0
- data/lib/openhab/osgi.rb +7 -0
- data/lib/openhab/version.rb +1 -1
- metadata +14 -6
- data/lib/openhab/core/dsl/rule/item.rb +0 -203
- data/lib/openhab/core/dsl/rule/triggers.rb +0 -77
@@ -15,6 +15,7 @@ module OpenHAB
|
|
15
15
|
extend Forwardable
|
16
16
|
include Comparable
|
17
17
|
|
18
|
+
# @return [Regex] Regular expression matching blank strings
|
18
19
|
BLANK_RE = /\A[[:space:]]*\z/.freeze
|
19
20
|
private_constant :BLANK_RE
|
20
21
|
|
@@ -33,7 +34,8 @@ module OpenHAB
|
|
33
34
|
#
|
34
35
|
# Convert the StringItem into a String
|
35
36
|
#
|
36
|
-
# @return [String] String representation of the StringItem or
|
37
|
+
# @return [String] String representation of the StringItem or
|
38
|
+
# nil if underlying OpenHAB StringItem does not have a state
|
37
39
|
#
|
38
40
|
def to_str
|
39
41
|
@string_item.state&.to_full_string&.to_s
|
@@ -64,7 +66,8 @@ module OpenHAB
|
|
64
66
|
#
|
65
67
|
# @param [Object] other object to compare to
|
66
68
|
#
|
67
|
-
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
69
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
70
|
+
# nil comparison to supplied object is not possible.
|
68
71
|
#
|
69
72
|
def <=>(other)
|
70
73
|
case other
|
@@ -72,6 +75,8 @@ module OpenHAB
|
|
72
75
|
@string_item.state <=> other.state
|
73
76
|
when String
|
74
77
|
@string_item.state.to_s <=> other
|
78
|
+
else
|
79
|
+
@string_item.state <=> other
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
@@ -87,7 +92,7 @@ module OpenHAB
|
|
87
92
|
def method_missing(meth, *args, &block)
|
88
93
|
if @string_item.respond_to?(meth)
|
89
94
|
@string_item.__send__(meth, *args, &block)
|
90
|
-
elsif @string_item.state
|
95
|
+
elsif @string_item.state&.to_full_string&.to_s.respond_to?(meth)
|
91
96
|
@string_item.state.to_full_string.to_s.__send__(meth, *args, &block)
|
92
97
|
elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
|
93
98
|
::Kernel.instance_method(meth).bind_call(self, *args, &block)
|
@@ -95,6 +100,21 @@ module OpenHAB
|
|
95
100
|
super(meth, *args, &block)
|
96
101
|
end
|
97
102
|
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Checks if this method responds to the missing method
|
106
|
+
#
|
107
|
+
# @param [String] method_name Name of the method to check
|
108
|
+
# @param [Boolean] _include_private boolean if private methods should be checked
|
109
|
+
#
|
110
|
+
# @return [Boolean] true if this object will respond to the supplied method, false otherwise
|
111
|
+
#
|
112
|
+
def respond_to_missing?(method_name, _include_private = false)
|
113
|
+
@string_item.respond_to?(method_name) ||
|
114
|
+
@string_item.state&.to_full_string&.to_s.respond_to?(method_name) ||
|
115
|
+
::Kernel.method_defined?(method_name) ||
|
116
|
+
::Kernel.private_method_defined?(method_name)
|
117
|
+
end
|
98
118
|
end
|
99
119
|
end
|
100
120
|
end
|
@@ -96,12 +96,27 @@ class Java::OrgOpenhabCoreLibraryItems::DimmerItem
|
|
96
96
|
def <=>(other)
|
97
97
|
logger.trace("Comparing #{self} to #{other}")
|
98
98
|
case other
|
99
|
-
when
|
100
|
-
|
101
|
-
when
|
102
|
-
|
99
|
+
when Java::OrgOpenhabCoreItems::GenericItem, NumberItem then state <=> other.state
|
100
|
+
when DecimalType then state <=> other
|
101
|
+
when Numeric then state.to_big_decimal.to_d <=> other.to_d
|
102
|
+
else compare_to(other)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Coerce objects into a DimmerItem
|
108
|
+
#
|
109
|
+
# @param [Object] other object to coerce to a DimmerItem if possible
|
110
|
+
#
|
111
|
+
# @return [Object] Numeric when applicable
|
112
|
+
#
|
113
|
+
def coerce(other)
|
114
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
115
|
+
case other
|
116
|
+
when Numeric
|
117
|
+
[other, state.to_big_decimal.to_d]
|
103
118
|
else
|
104
|
-
|
119
|
+
[other, state]
|
105
120
|
end
|
106
121
|
end
|
107
122
|
|
@@ -6,6 +6,7 @@ require 'bigdecimal'
|
|
6
6
|
|
7
7
|
# Monkey patch items
|
8
8
|
require 'openhab/core/dsl/monkey_patch/items/metadata'
|
9
|
+
require 'openhab/core/dsl/monkey_patch/items/persistence'
|
9
10
|
require 'openhab/core/dsl/monkey_patch/items/contact_item'
|
10
11
|
require 'openhab/core/dsl/monkey_patch/items/dimmer_item'
|
11
12
|
require 'openhab/core/dsl/monkey_patch/items/switch_item'
|
@@ -127,4 +128,5 @@ class Java::OrgOpenhabCoreItems::GenericItem
|
|
127
128
|
# rubocop:enable Style/ClassAndModuleChildren
|
128
129
|
prepend OpenHAB::Core::DSL::MonkeyPatch::Items::ItemExtensions
|
129
130
|
prepend OpenHAB::Core::DSL::MonkeyPatch::Items::Metadata
|
131
|
+
prepend OpenHAB::Core::DSL::MonkeyPatch::Items::Persistence
|
130
132
|
end
|
@@ -123,25 +123,7 @@ module OpenHAB
|
|
123
123
|
# @return [OpenHAB::Core::DSL::MonkeyPatch::Items::MetadataItem]
|
124
124
|
#
|
125
125
|
def []=(namespace, value)
|
126
|
-
|
127
|
-
when MetadataItem
|
128
|
-
meta_value = value.value
|
129
|
-
configuration = value.__getobj__
|
130
|
-
when Metadata
|
131
|
-
meta_value = value.value
|
132
|
-
configuration = value.configuration
|
133
|
-
when Array
|
134
|
-
raise ArgumentError, 'Array must contain 2 elements: value, config' if value.length < 2
|
135
|
-
|
136
|
-
meta_value = value[0]
|
137
|
-
configuration = value[1]
|
138
|
-
when Hash
|
139
|
-
meta_value = nil
|
140
|
-
configuration = value
|
141
|
-
else
|
142
|
-
meta_value = value
|
143
|
-
configuration = nil
|
144
|
-
end
|
126
|
+
meta_value, configuration = update_from_value(value)
|
145
127
|
|
146
128
|
key = MetadataKey.new(namespace, @item_name)
|
147
129
|
metadata = Metadata.new(key, meta_value, configuration)
|
@@ -185,12 +167,12 @@ module OpenHAB
|
|
185
167
|
#
|
186
168
|
# @return [Boolean] True if the given namespace exists, false otherwise
|
187
169
|
#
|
188
|
-
def
|
170
|
+
def key?(namespace)
|
189
171
|
!NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name)).nil?
|
190
172
|
end
|
191
173
|
|
192
|
-
alias
|
193
|
-
alias include?
|
174
|
+
alias has_key? key?
|
175
|
+
alias include? key?
|
194
176
|
|
195
177
|
#
|
196
178
|
# Merge the given hash with the current metadata. Existing namespace that matches the name
|
@@ -201,25 +183,9 @@ module OpenHAB
|
|
201
183
|
|
202
184
|
others.each do |other|
|
203
185
|
case other
|
204
|
-
when Hash
|
205
|
-
|
206
|
-
|
207
|
-
current_meta = self[key]&.to_a
|
208
|
-
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
209
|
-
end
|
210
|
-
self[key] = new_meta
|
211
|
-
end
|
212
|
-
when self.class
|
213
|
-
other.each do |key, new_value, new_config|
|
214
|
-
new_meta = new_value, new_config
|
215
|
-
if block_given?
|
216
|
-
current_meta = self[key]&.to_a
|
217
|
-
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
218
|
-
end
|
219
|
-
self[key] = new_meta
|
220
|
-
end
|
221
|
-
else
|
222
|
-
raise ArgumentError, "merge only supports Hash, or another item's metadata"
|
186
|
+
when Hash then merge_hash!(other)
|
187
|
+
when self.class then merge_metadata!(other)
|
188
|
+
else raise ArgumentError, "merge only supports Hash, or another item's metadata"
|
223
189
|
end
|
224
190
|
end
|
225
191
|
self
|
@@ -238,7 +204,65 @@ module OpenHAB
|
|
238
204
|
# @return [Java::org::openhab::core::items::MetadataRegistry]
|
239
205
|
#
|
240
206
|
def self.registry
|
241
|
-
|
207
|
+
@registry ||= OpenHAB::OSGI.service('org.openhab.core.items.MetadataRegistry')
|
208
|
+
end
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
#
|
213
|
+
# perform an updated based on the supplied value
|
214
|
+
#
|
215
|
+
# @param [MetadataItem,Metadata,Array,Hash] value to perform update from
|
216
|
+
#
|
217
|
+
# @return [Array<Object,Hash>] Array containing the value and configuration based on the
|
218
|
+
# the supplied object
|
219
|
+
#
|
220
|
+
def update_from_value(value)
|
221
|
+
case value
|
222
|
+
when MetadataItem then [value.value, value.__getobj__]
|
223
|
+
when Metadata then [value.value, value.configuration]
|
224
|
+
when Array
|
225
|
+
raise ArgumentError, 'Array must contain 2 elements: value, config' if value.length != 2
|
226
|
+
|
227
|
+
value
|
228
|
+
when Hash then [nil, value]
|
229
|
+
else [value, nil]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
#
|
234
|
+
# Merge the metadata from the supplied other metadata object
|
235
|
+
#
|
236
|
+
# @param [Hash] other metadata object to merge
|
237
|
+
# @yield [key, current_metadata, new_meta] to process merge
|
238
|
+
#
|
239
|
+
#
|
240
|
+
def merge_metadata!(other)
|
241
|
+
other.each do |key, new_value, new_config|
|
242
|
+
new_meta = new_value, new_config
|
243
|
+
if block_given?
|
244
|
+
current_meta = self[key]&.to_a
|
245
|
+
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
246
|
+
end
|
247
|
+
self[key] = new_meta
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
# Merge a hash into the metadata
|
253
|
+
#
|
254
|
+
# @param [Hash] other to merge into metadata
|
255
|
+
# @yield [key, current_metadata, new_meta] to process merge
|
256
|
+
#
|
257
|
+
#
|
258
|
+
def merge_hash!(other)
|
259
|
+
other.each do |key, new_meta|
|
260
|
+
if block_given?
|
261
|
+
current_meta = self[key]&.to_a
|
262
|
+
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
263
|
+
end
|
264
|
+
self[key] = new_meta
|
265
|
+
end
|
242
266
|
end
|
243
267
|
end
|
244
268
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module Core
|
5
|
+
module DSL
|
6
|
+
module MonkeyPatch
|
7
|
+
module Items
|
8
|
+
#
|
9
|
+
# Persistence extension for Items
|
10
|
+
#
|
11
|
+
module Persistence
|
12
|
+
%w[persist last_update].each do |method|
|
13
|
+
define_method(method) do |service = nil|
|
14
|
+
service ||= persistence_service
|
15
|
+
PersistenceExtensions.public_send(method, self, service&.to_s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Return the previous state of the item
|
21
|
+
#
|
22
|
+
# @param skip_equal [Boolean] if true, skips equal state values and
|
23
|
+
# searches the first state not equal the current state
|
24
|
+
# @param service [String] the name of the PersistenceService to use
|
25
|
+
#
|
26
|
+
# @return the previous state or nil if no previous state could be found,
|
27
|
+
# or if the default persistence service is not configured or
|
28
|
+
# does not refer to a valid service
|
29
|
+
#
|
30
|
+
def previous_state(service = nil, skip_equal: false)
|
31
|
+
service ||= persistence_service
|
32
|
+
PersistenceExtensions.previous_state(self, skip_equal, service&.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
%w[
|
36
|
+
average_since
|
37
|
+
changed_since
|
38
|
+
delta_since
|
39
|
+
deviation_since
|
40
|
+
evolution_rate
|
41
|
+
historic_state
|
42
|
+
maximum_since
|
43
|
+
minimum_since
|
44
|
+
sum_since
|
45
|
+
updated_since
|
46
|
+
variance_since
|
47
|
+
].each do |method|
|
48
|
+
define_method(method) do |timestamp, service = nil|
|
49
|
+
service ||= persistence_service
|
50
|
+
if timestamp.is_a? Java::JavaTimeTemporal::TemporalAmount
|
51
|
+
timestamp = Java::JavaTime::ZonedDateTime.now.minus(timestamp)
|
52
|
+
end
|
53
|
+
PersistenceExtensions.public_send(method, self, timestamp, service&.to_s)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
#
|
60
|
+
# Get the specified persistence service from the current thread local variable
|
61
|
+
#
|
62
|
+
# @return [Object] Persistence service name as String or Symbol, or nil if not set
|
63
|
+
#
|
64
|
+
def persistence_service
|
65
|
+
Thread.current.thread_variable_get(:persistence_service)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -74,7 +74,8 @@ class Java::OrgOpenhabCoreLibraryItems::SwitchItem
|
|
74
74
|
#
|
75
75
|
# @param [Object] other object to compare to
|
76
76
|
#
|
77
|
-
# @return [Boolean] True if other is a OnOffType and other equals state for this switch item,
|
77
|
+
# @return [Boolean] True if other is a OnOffType and other equals state for this switch item,
|
78
|
+
# otherwise result from super
|
78
79
|
#
|
79
80
|
def ==(other)
|
80
81
|
if other.is_a? OnOffType
|
@@ -24,7 +24,8 @@ module OpenHAB
|
|
24
24
|
#
|
25
25
|
# @param [Object] other object to compare for case equals
|
26
26
|
#
|
27
|
-
# @return [Boolean] if other is DimmerItem and state is covered by range,
|
27
|
+
# @return [Boolean] if other is DimmerItem and state is covered by range,
|
28
|
+
# result from parent Range class if not DimmerItem
|
28
29
|
#
|
29
30
|
def ===(other)
|
30
31
|
return super unless other.is_a? DimmerItem
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openhab/core/dsl/types/quantity'
|
4
|
+
|
5
|
+
module OpenHAB
|
6
|
+
module Core
|
7
|
+
module DSL
|
8
|
+
module MonkeyPatch
|
9
|
+
module Ruby
|
10
|
+
#
|
11
|
+
# Extend String class
|
12
|
+
#
|
13
|
+
module StringExtensions
|
14
|
+
include OpenHAB::Core
|
15
|
+
|
16
|
+
#
|
17
|
+
# Compares String to another object
|
18
|
+
#
|
19
|
+
# @param [Object] other object to compare to
|
20
|
+
#
|
21
|
+
# @return [Boolean] true if the two objects contain the same value, false otherwise
|
22
|
+
#
|
23
|
+
def ==(other)
|
24
|
+
case other
|
25
|
+
when OpenHAB::Core::DSL::Types::Quantity, QuantityType
|
26
|
+
other == self
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Prepend String class with comparison extensions
|
40
|
+
#
|
41
|
+
class String
|
42
|
+
prepend OpenHAB::Core::DSL::MonkeyPatch::Ruby::StringExtensions
|
43
|
+
end
|
@@ -10,15 +10,51 @@ class Java::OrgOpenhabCoreLibraryTypes::DecimalType
|
|
10
10
|
# rubocop:enable Style/ClassAndModuleChildren
|
11
11
|
|
12
12
|
#
|
13
|
-
# Compare
|
13
|
+
# Compare DecimalType to supplied object
|
14
14
|
#
|
15
15
|
# @param [Object] other object to compare to
|
16
16
|
#
|
17
|
-
# @return [
|
17
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied, nil comparison to supplied object is not possible.
|
18
18
|
#
|
19
|
-
def
|
20
|
-
|
19
|
+
def <=>(other)
|
20
|
+
logger.trace("#{self.class} #{self} <=> #{other} (#{other.class})")
|
21
|
+
case other
|
22
|
+
when Numeric
|
23
|
+
to_big_decimal.compare_to(other.to_d)
|
24
|
+
when Java::OrgOpenhabCoreTypes::UnDefType
|
25
|
+
1
|
26
|
+
else
|
27
|
+
other = other.state if other.respond_to? :state
|
28
|
+
compare_to(other)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Coerce objects into a DecimalType
|
34
|
+
#
|
35
|
+
# @param [Object] other object to coerce to a DecimalType if possible
|
36
|
+
#
|
37
|
+
# @return [Object] Numeric when applicable
|
38
|
+
#
|
39
|
+
def coerce(other)
|
40
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
41
|
+
case other
|
42
|
+
when Numeric
|
43
|
+
[other.to_d, to_big_decimal]
|
44
|
+
else
|
45
|
+
[other, self]
|
46
|
+
end
|
47
|
+
end
|
21
48
|
|
22
|
-
|
49
|
+
#
|
50
|
+
# Compare self to other through the spaceship operator
|
51
|
+
#
|
52
|
+
# @param [Object] other object to compare to
|
53
|
+
#
|
54
|
+
# @return [Boolean] True if equals
|
55
|
+
#
|
56
|
+
def ==(other)
|
57
|
+
logger.trace("#{self.class} #{self} == #{other} (#{other.class})")
|
58
|
+
(self <=> other).zero?
|
23
59
|
end
|
24
60
|
end
|