openhab-scripting 5.43.0 → 5.44.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/events/abstract_event.rb +14 -1
- data/lib/openhab/core/events/source.rb +308 -0
- data/lib/openhab/core/profile_factory.rb +1 -1
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +1 -1
- data/lib/openhab/rspec/mocks/persistence_service.rb +0 -4
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 14e2d94024913efabc184b537c27841fcba1136785987bd7b1423e0cde7fc072
|
|
4
|
+
data.tar.gz: c6e1746a22bba5b3e78f3f4e32dd2a5f09fdef208b098fe08558c13ff03d34e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41eb14f924ddfb42ea4add71eec184f0c1478b82fd129caf63bade3098e868ff78c432a7b4390ecc105b0bc22745da415b848d2f4f2b44decfffec7f8aecbf37
|
|
7
|
+
data.tar.gz: ee38fa1780d063681b6c710f4aee272ef0de6cb356a18acbe603d1e666596ffc74572d7da698084aaf6849f94b2b62396d5b4d255493b38a3ad3c9109b550af7
|
|
@@ -34,7 +34,20 @@ module OpenHAB
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# @!attribute [r] source
|
|
37
|
-
# @return [
|
|
37
|
+
# @return [Source, nil] The component(s) that sent the event.
|
|
38
|
+
def source
|
|
39
|
+
unless instance_variable_defined?(:@source)
|
|
40
|
+
begin
|
|
41
|
+
# Disable "instance vars on non-persistent Java type"
|
|
42
|
+
original_verbose = $VERBOSE
|
|
43
|
+
$VERBOSE = nil
|
|
44
|
+
@source = get_source && Source.new(get_source)
|
|
45
|
+
ensure
|
|
46
|
+
$VERBOSE = original_verbose
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
@source
|
|
50
|
+
end
|
|
38
51
|
|
|
39
52
|
#
|
|
40
53
|
# Returns the event payload as a Hash.
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Events
|
|
8
|
+
#
|
|
9
|
+
# Represents the source of an event as a chain of delegated {Component Components}.
|
|
10
|
+
#
|
|
11
|
+
# This class behaves like a String representing the event source, but also provides
|
|
12
|
+
# methods to access the individual components in the delegation chain.
|
|
13
|
+
#
|
|
14
|
+
# Starting from openHAB 5.1, the source can contain multiple components
|
|
15
|
+
# that contain information about the delegation chain of the event.
|
|
16
|
+
#
|
|
17
|
+
# Each {Source::Component component} contains:
|
|
18
|
+
# - {Source::Component#bundle bundle}: The module or app.
|
|
19
|
+
# For example: `org.openhab.automation.jrubyscripting` when a rule sends a command,
|
|
20
|
+
# or `org.openhab.core.io.rest` when a command comes from the REST API (UI).
|
|
21
|
+
# - {Source::Component#actor actor}: Optional. The rule, user or thinguid
|
|
22
|
+
# (e.g., "lighting_rule", "mqtt:topic:livingroom-switch:switch4")
|
|
23
|
+
#
|
|
24
|
+
# @example Log commands with source information
|
|
25
|
+
# rule "Log item commands" do
|
|
26
|
+
# received_command MyItem
|
|
27
|
+
# run do |event|
|
|
28
|
+
# logger.info "#{MyItem.name} received command #{event.command} from: #{event.source}"
|
|
29
|
+
# logger.info " Source components:"
|
|
30
|
+
# event.source.components.each_with_index do |component, index|
|
|
31
|
+
# logger.info " #{index}: bundle=#{component.bundle}, actor=#{component.actor}"
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# @example Ignore commands from specific integrations
|
|
37
|
+
# rule "Ignore UI commands" do
|
|
38
|
+
# received_command MyItem
|
|
39
|
+
# run do |event|
|
|
40
|
+
# next if event.source.sender?("org.openhab.core.io.rest")
|
|
41
|
+
# # process the command
|
|
42
|
+
# end
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# @see https://www.openhab.org/docs/developer/utils/events.html#the-core-events
|
|
46
|
+
# @see AbstractEvent#source
|
|
47
|
+
# @see OpenHAB::DSL.profile
|
|
48
|
+
#
|
|
49
|
+
class Source < Delegator
|
|
50
|
+
# The components in the event source delegation chain.
|
|
51
|
+
# @return [Array<Component>]
|
|
52
|
+
attr_reader :components
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Construct a new {Source} object.
|
|
56
|
+
#
|
|
57
|
+
# @overload initialize(source)
|
|
58
|
+
# @param [String] source The event source as a string.
|
|
59
|
+
#
|
|
60
|
+
# @overload initialize(components)
|
|
61
|
+
# @param [Array<Component>] components The components in the event source delegation chain.
|
|
62
|
+
#
|
|
63
|
+
def initialize(source_or_components) # rubocop:disable Lint/MissingSuper
|
|
64
|
+
@components = if source_or_components.is_a?(Array)
|
|
65
|
+
@source = nil
|
|
66
|
+
source_or_components.dup
|
|
67
|
+
else
|
|
68
|
+
@source = -source_or_components
|
|
69
|
+
@source.split("=>").map { |s| Component.parse(s) }
|
|
70
|
+
end.freeze
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Construct a new {Source} by adding an additional component to the delegation chain.
|
|
75
|
+
#
|
|
76
|
+
# @param [String] bundle The bundle (module, app, etc.) of the new component to add to the chain.
|
|
77
|
+
# @param [String, nil] actor The actor (user, device, etc.) of the new component to add to the chain.
|
|
78
|
+
# @return [Source]
|
|
79
|
+
#
|
|
80
|
+
def delegate(bundle, actor = nil)
|
|
81
|
+
Source.new(components + [Component.build(bundle, actor)])
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Check if the event was sent by the specified bundle or actor.
|
|
86
|
+
#
|
|
87
|
+
# Checks if any component matches the specified bundle or actor.
|
|
88
|
+
#
|
|
89
|
+
# @overload sender?(bundle_or_actor)
|
|
90
|
+
# @param [#===] bundle_or_actor
|
|
91
|
+
# The bundle (module, app, etc.) or actor (user, device, etc.) to check.
|
|
92
|
+
# If either a bundle or actor in any component in the source matches, this method returns true.
|
|
93
|
+
# @return [true, false]
|
|
94
|
+
#
|
|
95
|
+
# @overload sender?(bundle: nil, actor: nil)
|
|
96
|
+
# @param [#===] bundle
|
|
97
|
+
# @param [#===] actor
|
|
98
|
+
# @return [true, false]
|
|
99
|
+
#
|
|
100
|
+
def sender?(bundle_or_actor = nil, bundle: nil, actor: nil)
|
|
101
|
+
unless bundle_or_actor || bundle || actor
|
|
102
|
+
raise ArgumentError, "Specify one of bundle_or_actor, bundle or actor"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# rubocop:disable Style/CaseEquality
|
|
106
|
+
components.any? do |sender|
|
|
107
|
+
(bundle && bundle === sender.bundle) ||
|
|
108
|
+
(actor && actor === sender.actor) ||
|
|
109
|
+
(bundle_or_actor && bundle_or_actor === sender.bundle) ||
|
|
110
|
+
(bundle_or_actor && bundle_or_actor === sender.actor)
|
|
111
|
+
end
|
|
112
|
+
# rubocop:enable Style/CaseEquality
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# @param [#===] bundle The bundle (module, app, etc.) to find the actor for.
|
|
117
|
+
# @return [String, nil] the actor (user, device, etc.) for the specified bundle, if any.
|
|
118
|
+
#
|
|
119
|
+
def actor_for(bundle)
|
|
120
|
+
components.find { |c| bundle === c.bundle }&.actor # rubocop:disable Style/CaseEquality
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Construct a new {Source} without any components from the specified bundle.
|
|
125
|
+
#
|
|
126
|
+
# This is useful if you consider events from a specific bundle as sensitive,
|
|
127
|
+
# and want to filter that component out from an untrusted sender.
|
|
128
|
+
#
|
|
129
|
+
# @overload reject(bundle)
|
|
130
|
+
# @param [#===] bundle The bundle (module, app, etc.) to reject.
|
|
131
|
+
# @return [Source] a new Source without any components from the specified bundle.
|
|
132
|
+
#
|
|
133
|
+
# @overload reject { |component| ... }
|
|
134
|
+
# @yieldparam [Component] component Each component in the delegation chain.
|
|
135
|
+
# @return [Source] a new Source without any components for which the block returns true.
|
|
136
|
+
#
|
|
137
|
+
def reject(bundle = nil, &)
|
|
138
|
+
raise ArgumentError, "Either a bundle or a block must be given" unless bundle || block_given?
|
|
139
|
+
|
|
140
|
+
Source.new(if block_given?
|
|
141
|
+
components.reject(&)
|
|
142
|
+
else
|
|
143
|
+
components.reject { |c| bundle === c.bundle } # rubocop:disable Style/CaseEquality
|
|
144
|
+
end)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# @attribute [r] source
|
|
148
|
+
#
|
|
149
|
+
# The event source as a string.
|
|
150
|
+
#
|
|
151
|
+
# @return [String]
|
|
152
|
+
#
|
|
153
|
+
def source
|
|
154
|
+
@source ||= components.join("=>").freeze
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @attribute [r] bundle
|
|
158
|
+
#
|
|
159
|
+
# The bundle (module, app, etc.) of the initial component that sent the event.
|
|
160
|
+
#
|
|
161
|
+
# @return [String, nil]
|
|
162
|
+
#
|
|
163
|
+
def bundle
|
|
164
|
+
components.first&.bundle
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# @attribute [r] actor
|
|
168
|
+
#
|
|
169
|
+
# The actor (user, device, etc.) of the initial component that sent the event.
|
|
170
|
+
#
|
|
171
|
+
# @return [String, nil]
|
|
172
|
+
#
|
|
173
|
+
def actor
|
|
174
|
+
components.first&.actor
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
alias_method :to_s, :source
|
|
178
|
+
alias_method :to_str, :source
|
|
179
|
+
alias_method :inspect, :source
|
|
180
|
+
alias_method :__getobj__, :source
|
|
181
|
+
|
|
182
|
+
# @return [true, false]
|
|
183
|
+
def ==(other)
|
|
184
|
+
return components == other.components if other.is_a?(Source)
|
|
185
|
+
return to_s == other.to_str if other.respond_to?(:to_str)
|
|
186
|
+
|
|
187
|
+
false
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @return [true, false]
|
|
191
|
+
def !=(other)
|
|
192
|
+
!(self == other) # rubocop:disable Style/InverseMethods
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# @return [Integer, nil]
|
|
196
|
+
def <=>(other)
|
|
197
|
+
return 0 if self == other
|
|
198
|
+
return nil unless other.respond_to?(:to_str)
|
|
199
|
+
|
|
200
|
+
to_s <=> other.to_str
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def eql?(other)
|
|
204
|
+
other.is_a?(Source) && components == other.components
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @return [Integer]
|
|
208
|
+
def hash
|
|
209
|
+
components.hash
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Represents a single component in the event source delegation chain.
|
|
213
|
+
class Component
|
|
214
|
+
include Comparable
|
|
215
|
+
|
|
216
|
+
# The bundle (module, app, etc.) that sent the event.
|
|
217
|
+
# @return [String]
|
|
218
|
+
attr_reader :bundle
|
|
219
|
+
|
|
220
|
+
# The actor (user, device, etc.) that sent the event.
|
|
221
|
+
# @return [String]
|
|
222
|
+
attr_reader :actor
|
|
223
|
+
|
|
224
|
+
class << self
|
|
225
|
+
#
|
|
226
|
+
# Parse a {Component} from its string representation.
|
|
227
|
+
#
|
|
228
|
+
# @param [String] component The string representation of the {Component}.
|
|
229
|
+
# @return [Component]
|
|
230
|
+
#
|
|
231
|
+
def parse(component)
|
|
232
|
+
new(*component.split("$", 2))
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
#
|
|
236
|
+
# Build a {Component} from the specified bundle and actor.
|
|
237
|
+
#
|
|
238
|
+
# @param [String] bundle The bundle (module, app, etc.) that sent the event.
|
|
239
|
+
# @param [String, nil] actor The actor (user, device, etc.) that sent the event.
|
|
240
|
+
# @return [Component]
|
|
241
|
+
#
|
|
242
|
+
def build(bundle, actor = nil)
|
|
243
|
+
if AbstractEvent.respond_to?(:build_source)
|
|
244
|
+
# a bit round-about, but is necessary for argument validation
|
|
245
|
+
# and escaping
|
|
246
|
+
# Only present in openHAB 5.1+
|
|
247
|
+
begin
|
|
248
|
+
parse(AbstractEvent.build_source(bundle, actor))
|
|
249
|
+
rescue java.lang.IllegalArgumentException => e
|
|
250
|
+
raise ArgumentError, e.message
|
|
251
|
+
end
|
|
252
|
+
else
|
|
253
|
+
new(bundle, actor)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# @return [String]
|
|
259
|
+
def to_s
|
|
260
|
+
if actor
|
|
261
|
+
"#{bundle}$#{actor}"
|
|
262
|
+
else
|
|
263
|
+
bundle
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
alias_method :to_str, :to_s
|
|
267
|
+
|
|
268
|
+
# @return [true, false]
|
|
269
|
+
def ==(other)
|
|
270
|
+
return bundle == other.bundle && actor == other.actor if other.is_a?(Component)
|
|
271
|
+
return to_s == other.to_str if other.respond_to?(:to_str)
|
|
272
|
+
|
|
273
|
+
false
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @return [true, false]
|
|
277
|
+
def !=(other)
|
|
278
|
+
!(self == other) # rubocop:disable Style/InverseMethods
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# @return [Integer, nil]
|
|
282
|
+
def <=>(other)
|
|
283
|
+
return 0 if self == other
|
|
284
|
+
return nil unless other.respond_to?(:to_str)
|
|
285
|
+
|
|
286
|
+
to_s <=> other.to_str
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def eql?(other)
|
|
290
|
+
other.is_a?(Component) && bundle == other.bundle && actor == other.actor
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# @return [Integer]
|
|
294
|
+
def hash
|
|
295
|
+
[bundle, actor].hash
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
private
|
|
299
|
+
|
|
300
|
+
def initialize(bundle, actor = nil)
|
|
301
|
+
@bundle = bundle
|
|
302
|
+
@actor = actor
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
@@ -92,7 +92,7 @@ module OpenHAB
|
|
|
92
92
|
params[:command] ||= nil
|
|
93
93
|
params[:trigger] ||= nil
|
|
94
94
|
params[:time_series] ||= nil
|
|
95
|
-
params[:source]
|
|
95
|
+
params[:source] = (params[:source] && Core::Events::Source.new(params[:source])) || nil
|
|
96
96
|
|
|
97
97
|
kwargs = {}
|
|
98
98
|
@block.parameters.each do |(param_type, name)|
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
|
@@ -158,7 +158,7 @@ module OpenHAB
|
|
|
158
158
|
# @yieldparam [Core::Things::ChannelUID] channel_uid The linked channel.
|
|
159
159
|
# @yieldparam [Hash] configuration The profile configuration.
|
|
160
160
|
# @yieldparam [org.openhab.core.thing.profiles.ProfileContext] context The profile context.
|
|
161
|
-
# @yieldparam [
|
|
161
|
+
# @yieldparam [Core::Events::Source, nil] source The source of the event.
|
|
162
162
|
# @since openHAB 5.1
|
|
163
163
|
# @yieldreturn [Boolean] Return true from the block in order to have default processing.
|
|
164
164
|
# @return [void]
|
|
@@ -109,10 +109,6 @@ module OpenHAB
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def get_default_strategies # rubocop:disable Naming/AccessorMethodName -- must match Java interface
|
|
113
|
-
[org.openhab.core.persistence.strategy.PersistenceStrategy::Globals::CHANGE]
|
|
114
|
-
end
|
|
115
|
-
|
|
116
112
|
private
|
|
117
113
|
|
|
118
114
|
def query_internal(filter, &)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openhab-scripting
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.44.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian O'Connell
|
|
@@ -96,6 +96,7 @@ files:
|
|
|
96
96
|
- lib/openhab/core/events/item_state_event.rb
|
|
97
97
|
- lib/openhab/core/events/item_state_updated_event.rb
|
|
98
98
|
- lib/openhab/core/events/item_time_series_updated_event.rb
|
|
99
|
+
- lib/openhab/core/events/source.rb
|
|
99
100
|
- lib/openhab/core/events/startlevel_event.rb
|
|
100
101
|
- lib/openhab/core/events/thing_status_info_event.rb
|
|
101
102
|
- lib/openhab/core/events/timer_event.rb
|