openhab-scripting 2.14.0 → 2.16.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.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 +2 -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 +50 -24
- 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
|