openhab-scripting 5.8.0 → 5.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00dfdfae614d0fc89c09ddfe86b16c4d0b41e94bc1c2e73889eb359ff09ada3c
4
- data.tar.gz: ecafc5d2f33cf0b0015ac9e8c59449a57488e4f18316bd584e8dfe028d5ec4c7
3
+ metadata.gz: acf8ae7ed285c32bb11070e6ae64c54b9687dae7883c272be4a9ad30f399ed8c
4
+ data.tar.gz: 8820ac3849f07734843d2863ff483fbde70bfe56c41981f2d48ec2e8c7bd73a8
5
5
  SHA512:
6
- metadata.gz: eff4e5471afb074c92cd7d3fc01d9070a80db680ed79c4814dc8b88e14eb67c8f9215a77f80c6b1a9a5eb6f4e220b6ce5e38ba01f0287779821db918f81c0fef
7
- data.tar.gz: f187e831d86e87fe4a2e91b311f8bdd3c4e046e9107054ff74c91cdf7644d4fa303d86d8abf3c5f80e8e8cb1762f5c436b89e3e841a86ef05af351c6f0d6abbb
6
+ metadata.gz: ab2e153c20c4d81b4b4b5b7d3025d1f49812099ea1040eba85b03f6fc8ce4217d84a3204e1c0917ed53c8386220b25da7d1da4bc367b51459ef74d67a52d7d44
7
+ data.tar.gz: 0bdc096799e02f344f7d24c218af6ed045840c9a87ab890e81a339896801c53c6e18a6dabafd060e2c18023b69da8fdb4df9d3d58fcab3917baba6274fe992eb
@@ -10,6 +10,9 @@ module OpenHAB
10
10
  # @return [Object]
11
11
  attr_accessor :attachment
12
12
 
13
+ # @return [Hash]
14
+ attr_accessor :inputs
15
+
13
16
  # @return [String]
14
17
  alias_method :inspect, :to_s
15
18
 
@@ -16,6 +16,25 @@ module OpenHAB
16
16
  def item
17
17
  EntityLookup.lookup_item(item_name)
18
18
  end
19
+
20
+ #
21
+ # @!attribute [r] group
22
+ #
23
+ # Returns the group item whose member had triggered this event.
24
+ #
25
+ # This is the equivalent of openHAB's `triggeringGroup`, and it is only available
26
+ # on a member-of-group trigger.
27
+ #
28
+ # @return [Item,nil] The group item whose member had triggered this event.
29
+ # `nil` when the event wasn't triggered by a member-of-group trigger.
30
+ #
31
+ # @since openHAB 4.0 for file-based rules
32
+ # @since openHAB 4.1 for UI rules
33
+ #
34
+ def group
35
+ triggering_group = inputs&.[]("triggeringGroup") || $ctx&.[]("triggeringGroup")
36
+ Items::Proxy.new(triggering_group) if triggering_group
37
+ end
19
38
  end
20
39
  end
21
40
  end
@@ -251,6 +251,7 @@ module OpenHAB
251
251
  !(self.tags.to_a & tags).empty?
252
252
  end
253
253
 
254
+ # @!attribute thing [r]
254
255
  # Return the item's thing if this item is linked with a thing. If an item is linked to more than one thing,
255
256
  # this method only returns the first thing.
256
257
  #
@@ -260,6 +261,7 @@ module OpenHAB
260
261
  end
261
262
  alias_method :linked_thing, :thing
262
263
 
264
+ # @!attribute things [r]
263
265
  # Returns all of the item's linked things.
264
266
  #
265
267
  # @return [Array<Thing>] An array of things or an empty array
@@ -268,11 +270,80 @@ module OpenHAB
268
270
  end
269
271
  alias_method :all_linked_things, :things
270
272
 
273
+ #
274
+ # @!attribute links [r]
271
275
  # Returns all of the item's links (channels and link configurations).
272
276
  #
273
- # @return [Array<ItemChannelLink>] An array of ItemChannelLink or an empty array
277
+ # @return [ItemChannelLinks] An array of ItemChannelLink or an empty array
278
+ #
279
+ # @example Get the configuration of the first link
280
+ # LivingRoom_Light_Power.links.first.configuration
281
+ #
282
+ # @example Remove all managed links
283
+ # LivingRoom_Light_Power.links.clear
284
+ #
285
+ # @see link
286
+ # @see unlink
287
+ #
274
288
  def links
275
- Things::Links::Provider.registry.get_links(name)
289
+ ItemChannelLinks.new(self, Things::Links::Provider.registry.get_links(name))
290
+ end
291
+
292
+ #
293
+ # Links the item to a channel.
294
+ #
295
+ # @param [String, Things::Channel, Things::ChannelUID] channel The channel to link to.
296
+ # @param [Hash] config The configuration for the link.
297
+ #
298
+ # @return [Things::ItemChannelLink] The created link.
299
+ #
300
+ # @example Link an item to a channel
301
+ # LivingRoom_Light_Power.link("mqtt:topic:livingroom-light:power")
302
+ #
303
+ # @example Link to a Thing's channel
304
+ # LivingRoom_Light_Power.link(things["mqtt:topic:livingroom-light"].channels["power"])
305
+ #
306
+ # @example Specify a link configuration
307
+ # High_Temperature_Alert.link(
308
+ # "mqtt:topic:outdoor-thermometer:temperature",
309
+ # profile: "system:hysteresis",
310
+ # lower: "29 °C",
311
+ # upper: "30 °C")
312
+ #
313
+ # @see links
314
+ # @see unlink
315
+ #
316
+ def link(channel, config = {})
317
+ Core::Things::Links::Provider.create_link(self, channel, config).tap do |new_link|
318
+ provider = Core::Things::Links::Provider.current
319
+ if !(current_link = provider.get(new_link.uid))
320
+ provider.add(new_link)
321
+ elsif current_link.configuration != config
322
+ provider.update(new_link)
323
+ end
324
+ end
325
+ end
326
+
327
+ #
328
+ # Removes a link to a channel from managed link providers.
329
+ #
330
+ # @param [String, Things::Channel, Things::ChannelUID] channel The channel to remove the link to.
331
+ #
332
+ # @return [Things::ItemChannelLink, nil] The removed link, if found.
333
+ # @raise [FrozenError] if the link is not managed by a managed link provider.
334
+ #
335
+ # @see link
336
+ # @see links
337
+ #
338
+ def unlink(channel)
339
+ link_to_delete = Things::Links::Provider.create_link(self, channel, {})
340
+ provider = Things::Links::Provider.registry.provider_for(link_to_delete.uid)
341
+ unless provider.is_a?(ManagedProvider)
342
+ raise FrozenError,
343
+ "Cannot remove the link #{link_to_delete.uid} from non-managed provider #{provider.inspect}"
344
+ end
345
+
346
+ provider.remove(link_to_delete.uid)
276
347
  end
277
348
 
278
349
  # @return [String]
@@ -286,7 +357,8 @@ module OpenHAB
286
357
  "#{s}>"
287
358
  end
288
359
 
289
- # @return [org.openhab.core.common.registry.Provider, nil]
360
+ # @!attribute provider [r]
361
+ # @return [org.openhab.core.common.registry.Provider, nil] Returns the provider for this item.
290
362
  def provider
291
363
  Provider.registry.provider_for(self)
292
364
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Items
8
+ #
9
+ # A wrapper for {Item#links} delegated to Set<{org.openhab.core.thing.link.ItemChannelLink}>.
10
+ #
11
+ # Adds methods for clearing item's links to channels.
12
+ #
13
+ class ItemChannelLinks < SimpleDelegator
14
+ #
15
+ # @param [Item] item The item that the links belong to
16
+ # @param [Set<ItemChannelLink>] links The set of links to delegate to
17
+ #
18
+ # @!visibility private
19
+ def initialize(item, links)
20
+ super(links)
21
+ @item = item
22
+ end
23
+
24
+ #
25
+ # Removes all links to channels from managed link providers.
26
+ # @return [self]
27
+ #
28
+ def clear
29
+ Things::Links::Provider.registry.all.each do |link|
30
+ next unless link.item_name == @item.name
31
+
32
+ provider = Things::Links::Provider.registry.provider_for(link.uid)
33
+ if provider.is_a?(ManagedProvider)
34
+ provider.remove(link.uid)
35
+ else
36
+ logger.warn("Cannot remove the link #{link.uid} from non-managed provider #{provider.inspect}")
37
+ end
38
+ end
39
+ self
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -311,6 +311,11 @@ module OpenHAB
311
311
  synonyms = Array.wrap(synonyms).map { |s| s.to_s.strip }
312
312
 
313
313
  tags.map do |name, parent|
314
+ if (existing_tag = lookup(name))
315
+ logger.warn("Tag already exists: #{existing_tag.inspect}")
316
+ next
317
+ end
318
+
314
319
  unless parent.is_a?(SemanticTag)
315
320
  parent_tag = lookup(parent)
316
321
  raise ArgumentError, "Unknown parent: #{parent}" unless parent_tag
@@ -318,8 +323,6 @@ module OpenHAB
318
323
  parent = parent_tag
319
324
  end
320
325
 
321
- next if lookup(name)
322
-
323
326
  new_tag = org.openhab.core.semantics.SemanticTagImpl.new("#{parent.uid}_#{name}",
324
327
  label,
325
328
  description,
@@ -32,9 +32,14 @@ module OpenHAB
32
32
  def inspect
33
33
  r = "#<OpenHAB::Core::Things::Channel #{uid}"
34
34
  r += " #{label.inspect}" if label
35
- r += " auto_update_policy=#{auto_update_policy}" if auto_update_policy
35
+ r += " description=#{description.inspect}" if description
36
+ r += " kind=#{kind.inspect}"
37
+ r += " channel_type_uid=#{channel_type_uid.inspect}" if channel_type_uid
36
38
  r += " configuration=#{configuration.properties.to_h}" unless configuration.properties.empty?
37
39
  r += " properties=#{properties.to_h}" unless properties.empty?
40
+ r += " default_tags=#{default_tags.to_a}" unless default_tags.empty?
41
+ r += " auto_update_policy=#{auto_update_policy}" if auto_update_policy
42
+ r += " accepted_item_type=#{accepted_item_type}" if accepted_item_type
38
43
  "#{r}>"
39
44
  end
40
45
 
@@ -42,6 +47,34 @@ module OpenHAB
42
47
  def to_s
43
48
  uid.to_s
44
49
  end
50
+
51
+ # @deprecated OH3.4 this whole section is not needed in OH4+. Also see Thing#config_eql?
52
+ if Gem::Version.new(Core::VERSION) < Gem::Version.new("4.0.0")
53
+ # @!visibility private
54
+ module ChannelComparable
55
+ # @!visibility private
56
+ # This is only needed in OH3 because it is implemented in OH4 core
57
+ def ==(other)
58
+ return true if equal?(other)
59
+ return false unless other.is_a?(Channel)
60
+
61
+ %i[class
62
+ uid
63
+ label
64
+ description
65
+ kind
66
+ channel_type_uid
67
+ configuration
68
+ properties
69
+ default_tags
70
+ auto_update_policy
71
+ accepted_item_type].all? do |attr|
72
+ send(attr) == other.send(attr)
73
+ end
74
+ end
75
+ end
76
+ org.openhab.core.thing.binding.builder.ChannelBuilder.const_get(:ChannelImpl).prepend(ChannelComparable)
77
+ end
45
78
  end
46
79
  end
47
80
  end
@@ -42,8 +42,7 @@ module OpenHAB
42
42
  # @return [Array<Item>] An array of things or an empty array
43
43
  #
44
44
  def items
45
- registry = OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
46
- registry.get_linked_items(self).map { |i| Items::Proxy.new(i) }
45
+ Links::Provider.registry.get_linked_items(self).map { |i| Items::Proxy.new(i) }
47
46
  end
48
47
  end
49
48
  end
@@ -26,6 +26,12 @@ module OpenHAB
26
26
  DSL.items[item_name]
27
27
  end
28
28
 
29
+ # @!attribute [r] channel
30
+ # @return [Channel]
31
+ def channel
32
+ DSL.things[linked_uid.thing_uid].channels[linked_uid.id]
33
+ end
34
+
29
35
  alias_method :channel_uid, :linked_uid
30
36
  end
31
37
  end
@@ -8,44 +8,37 @@ module OpenHAB
8
8
  # and channels.
9
9
  #
10
10
  module ProfileCallback
11
- class << self
12
- #
13
- # Wraps the parent class's method to format non-Types.
14
- #
15
- # @!macro def_state_parsing_method
16
- # @!method $1($2)
17
- # @return [void]
18
- # @!visibility private
19
- def def_state_parsing_method(method, param_name)
20
- class_eval <<~RUBY, __FILE__, __LINE__ + 1
21
- def #{method}(type) # def handle_command(type)
22
- type = link.item.format_#{(param_name == :state) ? :update : param_name}(type) # type = link.item.format_command(type)
23
- super(type) # super(type)
24
- end # end
25
- RUBY
26
- end
27
- end
28
-
29
11
  #
30
12
  # Forward the given command to the respective thing handler.
31
13
  #
32
14
  # @param [Command] command
33
15
  #
34
- def_state_parsing_method(:handle_command, :command)
16
+ def handle_command(command)
17
+ @dummy_channel_item ||= DSL::Items::ItemBuilder.item_factory.create_item(link.channel.accepted_item_type,
18
+ "")
19
+ command = @dummy_channel_item.format_command(command)
20
+ super(command)
21
+ end
35
22
 
36
23
  #
37
24
  # Send a command to the framework.
38
25
  #
39
26
  # @param [Command] command
40
27
  #
41
- def_state_parsing_method(:send_command, :command)
28
+ def send_command(command)
29
+ command = link.item.format_command(command)
30
+ super(command)
31
+ end
42
32
 
43
33
  #
44
34
  # Send a state update to the framework.
45
35
  #
46
36
  # @param [State] state
47
37
  #
48
- def_state_parsing_method(:send_update, :state)
38
+ def send_update(state)
39
+ state = link.item.format_update(state)
40
+ super(state)
41
+ end
49
42
  end
50
43
  end
51
44
  end
@@ -29,7 +29,7 @@ module OpenHAB
29
29
  #
30
30
  # @return [Array] channels
31
31
  def channels
32
- Thing::ChannelsArray.new(super.to_a)
32
+ Thing::ChannelsArray.new(self, super.to_a)
33
33
  end
34
34
 
35
35
  #
@@ -64,13 +64,17 @@ module OpenHAB
64
64
  # Array wrapper class to allow searching a list of channels
65
65
  # by channel id
66
66
  class ChannelsArray < Array
67
+ def initialize(thing, array)
68
+ super(array)
69
+ @thing = thing
70
+ end
71
+
67
72
  # Allows indexing by both integer as an array or channel id acting like a hash.
68
- # @param [Integer, String] index Numeric index or string channel id to search for.
73
+ # @param [Integer, String, ChannelUID] index
74
+ # Numeric index, string channel id, or a {ChannelUID} to search for.
69
75
  def [](index)
70
- if index.respond_to?(:to_str)
71
- key = index.to_str
72
- return find { |channel| channel.uid.id == key }
73
- end
76
+ return @thing.get_channel(index) if index.is_a?(ChannelUID)
77
+ return @thing.get_channel(index.to_str) if index.respond_to?(:to_str)
74
78
 
75
79
  super
76
80
  end
@@ -204,7 +208,9 @@ module OpenHAB
204
208
  # @return [true,false] true if all attributes are equal, false otherwise
205
209
  #
206
210
  def config_eql?(other)
207
- %i[uid label channels bridge_uid location configuration].all? { |method| send(method) == other.send(method) }
211
+ # @deprecated OH3.4 - in OH4, channels can be included in the array and do not need to be compared separately
212
+ channels.to_a == other.channels.to_a &&
213
+ %i[uid label bridge_uid location configuration].all? { |method| send(method) == other.send(method) }
208
214
  end
209
215
 
210
216
  #
@@ -156,7 +156,6 @@ module OpenHAB
156
156
  item.update(builder.state) unless builder.state.nil?
157
157
 
158
158
  # make sure to add the item to the registry before linking it
159
- provider = Core::Things::Links::Provider.current
160
159
  channel_uids = builder.channels.to_set do |(channel, config)|
161
160
  # fill in partial channel names from group's thing id
162
161
  if !channel.include?(":") &&
@@ -165,17 +164,11 @@ module OpenHAB
165
164
  channel = "#{thing}:#{channel}"
166
165
  end
167
166
 
168
- new_link = Core::Things::Links::Provider.create_link(item, channel, config)
169
- if !(current_link = provider.get(new_link.uid))
170
- provider.add(new_link)
171
- elsif current_link.configuration != config
172
- provider.update(new_link)
173
- end
174
-
175
- new_link.linked_uid
167
+ item.link(channel, config).linked_uid
176
168
  end
177
169
 
178
170
  # remove links not in the new item
171
+ provider = Core::Things::Links::Provider.current
179
172
  provider.all.each do |link|
180
173
  provider.remove(link.uid) if link.item_name == item.name && !channel_uids.include?(link.linked_uid)
181
174
  end
@@ -149,6 +149,8 @@ module OpenHAB
149
149
  end
150
150
 
151
151
  event.attachment = attachment
152
+ # events that are not from AbstractEvent do not have inputs
153
+ event.inputs = inputs if event.respond_to?(:inputs=)
152
154
  return event
153
155
  end
154
156
 
@@ -257,7 +257,14 @@ module OpenHAB
257
257
  # The ChannelBuilder DSL allows you to customize a channel
258
258
  class ChannelBuilder
259
259
  attr_accessor :label
260
- attr_reader :uid, :config, :type
260
+ attr_reader :uid,
261
+ :config,
262
+ :type,
263
+ :default_tags,
264
+ :properties,
265
+ :description,
266
+ :auto_update_policy,
267
+ :accepted_item_type
261
268
 
262
269
  #
263
270
  # Constructor for ChannelBuilder
@@ -269,10 +276,27 @@ module OpenHAB
269
276
  # @param [String] label The channel label.
270
277
  # @param [thing] thing The thing associated with this channel.
271
278
  # This parameter is not needed for the {ThingBuilder#channel} method.
279
+ # @param [String] description The channel description.
272
280
  # @param [String] group The group name.
273
281
  # @param [Hash] config Channel configuration. The keys can be strings or symbols.
282
+ # @param [Hash] properties The channel properties.
283
+ # @param [String,Symbol,Semantics::Tag,Array<String,Symbol,Semantics::Tag>] default_tags
284
+ # The default tags for this channel.
285
+ # @param [:default, :recommend, :veto, org.openhab.core.thing.type.AutoUpdatePolicy] auto_update_policy
286
+ # The channel's auto update policy.
287
+ # @param [String] accepted_item_type The accepted item type.
274
288
  #
275
- def initialize(uid, type, label = nil, thing:, group: nil, config: {})
289
+ def initialize(uid,
290
+ type,
291
+ label = nil,
292
+ thing:,
293
+ description: nil,
294
+ group: nil,
295
+ config: nil,
296
+ properties: nil,
297
+ default_tags: nil,
298
+ auto_update_policy: nil,
299
+ accepted_item_type: nil)
276
300
  @thing = thing
277
301
 
278
302
  uid = uid.to_s
@@ -292,7 +316,14 @@ module OpenHAB
292
316
  end
293
317
  @type = type
294
318
  @label = label
295
- @config = config.transform_keys(&:to_s)
319
+ @config = config&.transform_keys(&:to_s)
320
+ @default_tags = Items::ItemBuilder.normalize_tags(*Array.wrap(default_tags))
321
+ @properties = properties&.transform_keys(&:to_s)
322
+ @description = description
323
+ @accepted_item_type = accepted_item_type
324
+ return unless auto_update_policy
325
+
326
+ @auto_update_policy = org.openhab.core.thing.type.AutoUpdatePolicy.value_of(auto_update_policy.to_s.upcase)
296
327
  end
297
328
 
298
329
  # @!visibility private
@@ -300,7 +331,15 @@ module OpenHAB
300
331
  org.openhab.core.thing.binding.builder.ChannelBuilder.create(uid)
301
332
  .with_kind(kind)
302
333
  .with_type(type)
303
- .with_configuration(Core::Configuration.new(config))
334
+ .tap do |builder|
335
+ builder.with_label(label) if label
336
+ builder.with_configuration(Core::Configuration.new(config)) if config && !config.empty?
337
+ builder.with_default_tags(Set.new(default_tags).to_java) unless default_tags.empty?
338
+ builder.with_properties(properties) if properties
339
+ builder.with_description(description) if description
340
+ builder.with_auto_update_policy(auto_update_policy) if auto_update_policy
341
+ builder.with_accepted_item_type(accepted_item_type) if accepted_item_type
342
+ end
304
343
  .build
305
344
  end
306
345
 
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.8.0"
7
+ VERSION = "5.10.0"
8
8
  end
9
9
  end
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.8.0
4
+ version: 5.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-10-07 00:00:00.000000000 Z
13
+ date: 2023-10-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -409,6 +409,7 @@ files:
409
409
  - lib/openhab/core/items/group_item.rb
410
410
  - lib/openhab/core/items/image_item.rb
411
411
  - lib/openhab/core/items/item.rb
412
+ - lib/openhab/core/items/item_channel_links.rb
412
413
  - lib/openhab/core/items/location_item.rb
413
414
  - lib/openhab/core/items/metadata.rb
414
415
  - lib/openhab/core/items/metadata/hash.rb