openhab-scripting 5.9.0 → 5.11.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 +3 -0
- data/lib/openhab/core/events/item_event.rb +19 -0
- data/lib/openhab/core/items/dimmer_item.rb +10 -0
- data/lib/openhab/core/items/generic_item.rb +7 -1
- data/lib/openhab/core/items/item.rb +75 -3
- data/lib/openhab/core/items/item_channel_links.rb +44 -0
- data/lib/openhab/core/items/player_item.rb +26 -0
- data/lib/openhab/core/items/rollershutter_item.rb +16 -0
- data/lib/openhab/core/items/semantics/enumerable.rb +19 -0
- data/lib/openhab/core/items/semantics.rb +5 -2
- data/lib/openhab/core/items/switch_item.rb +8 -0
- data/lib/openhab/core/items.rb +9 -3
- data/lib/openhab/core/things/channel_uid.rb +1 -2
- data/lib/openhab/core/things/item_channel_link.rb +6 -0
- data/lib/openhab/core/things/profile_callback.rb +15 -21
- data/lib/openhab/dsl/items/builder.rb +2 -9
- data/lib/openhab/dsl/items/ensure.rb +1 -1
- data/lib/openhab/dsl/rules/automation_rule.rb +2 -0
- data/lib/openhab/dsl/things/builder.rb +27 -12
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +43 -5
- data/lib/openhab/rspec/shell.rb +27 -17
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e7d078cc73659d0f435950d36438b67759b2e3b5c0abf80f258a36101792a0d
|
4
|
+
data.tar.gz: 2a76c20015d6320b64a2a9ea79557c7133b1101a8514fabba9241f91b455615d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc54b1fae7be3bee15b1af2c27526cf942a13741404dd1c0e61034b82d2d472703bfb48ef921d25ed608dbe3d9c964abbded85ab1d3adfd855847229c6bf2447
|
7
|
+
data.tar.gz: c454623c911c90be03464391f885b8ccebfd2789b5e9dbbe32a6f8309fdf7e1f948e2c0730373d383bf7892271ab752bf9d8c2197ed541cff7f33a692ea296ec
|
@@ -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
|
@@ -133,6 +133,16 @@ module OpenHAB
|
|
133
133
|
# Send the {DECREASE} command to the item
|
134
134
|
# @return [DimmerItem] `self`
|
135
135
|
|
136
|
+
# @!method increase!
|
137
|
+
# Send the {INCREASE} command to the item, even when
|
138
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
139
|
+
# @return [DimmerItem] `self`
|
140
|
+
|
141
|
+
# @!method decrease!
|
142
|
+
# Send the {DECREASE} command to the item, even when
|
143
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
144
|
+
# @return [DimmerItem] `self`
|
145
|
+
|
136
146
|
# raw numbers translate directly to PercentType, not a DecimalType
|
137
147
|
# @!visibility private
|
138
148
|
def format_type(command)
|
@@ -128,15 +128,19 @@ module OpenHAB
|
|
128
128
|
# Send a command to this item
|
129
129
|
#
|
130
130
|
# When this method is chained after the {OpenHAB::DSL::Items::Ensure::Ensurable#ensure ensure}
|
131
|
-
# method, or issued inside an {OpenHAB::DSL.ensure_states ensure_states} block,
|
131
|
+
# method, or issued inside an {OpenHAB::DSL.ensure_states ensure_states} block, or after
|
132
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} have been called,
|
132
133
|
# the command will only be sent if the item is not already in the same state.
|
133
134
|
#
|
135
|
+
# The similar method `command!`, however, will always send the command regardless of the item's state.
|
136
|
+
#
|
134
137
|
# @param [Command] command command to send to the item
|
135
138
|
# @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
|
136
139
|
# otherwise the item.
|
137
140
|
#
|
138
141
|
# @see DSL::Items::TimedCommand#command Timed Command
|
139
142
|
# @see OpenHAB::DSL.ensure_states ensure_states
|
143
|
+
# @see OpenHAB::DSL.ensure_states! ensure_states!
|
140
144
|
# @see DSL::Items::Ensure::Ensurable#ensure ensure
|
141
145
|
#
|
142
146
|
def command(command)
|
@@ -145,6 +149,7 @@ module OpenHAB
|
|
145
149
|
$events.send_command(self, command)
|
146
150
|
Proxy.new(self)
|
147
151
|
end
|
152
|
+
alias_method :command!, :command
|
148
153
|
|
149
154
|
# not an alias to allow easier stubbing and overriding
|
150
155
|
def <<(command)
|
@@ -170,6 +175,7 @@ module OpenHAB
|
|
170
175
|
$events.post_update(self, state)
|
171
176
|
Proxy.new(self)
|
172
177
|
end
|
178
|
+
alias_method :update!, :update
|
173
179
|
|
174
180
|
# @!visibility private
|
175
181
|
def format_command(command)
|
@@ -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 [
|
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
|
-
#
|
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
|
@@ -39,25 +39,51 @@ module OpenHAB
|
|
39
39
|
# Send the {PLAY} command to the item
|
40
40
|
# @return [PlayerItem] `self`
|
41
41
|
|
42
|
+
# @!method play!
|
43
|
+
# Send the {PLAY} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
44
|
+
# @return [PlayerItem] `self`
|
45
|
+
|
42
46
|
# @!method pause
|
43
47
|
# Send the {PAUSE} command to the item
|
44
48
|
# @return [PlayerItem] `self`
|
45
49
|
|
50
|
+
# @!method pause!
|
51
|
+
# Send the {PAUSE} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
52
|
+
# @return [PlayerItem] `self`
|
53
|
+
|
46
54
|
# @!method rewind
|
47
55
|
# Send the {REWIND} command to the item
|
48
56
|
# @return [PlayerItem] `self`
|
49
57
|
|
58
|
+
# @!method rewind
|
59
|
+
# Send the {REWIND} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
60
|
+
# @return [PlayerItem] `self`
|
61
|
+
|
50
62
|
# @!method fast_forward
|
51
63
|
# Send the {FASTFORWARD} command to the item
|
52
64
|
# @return [PlayerItem] `self`
|
53
65
|
|
66
|
+
# @!method fast_forward!
|
67
|
+
# Send the {FASTFORWARD} command to the item, even when
|
68
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
69
|
+
# @return [PlayerItem] `self`
|
70
|
+
|
54
71
|
# @!method next
|
55
72
|
# Send the {NEXT} command to the item
|
56
73
|
# @return [PlayerItem] `self`
|
57
74
|
|
75
|
+
# @!method next!
|
76
|
+
# Send the {NEXT} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
77
|
+
# @return [PlayerItem] `self`
|
78
|
+
|
58
79
|
# @!method previous
|
59
80
|
# Send the {PREVIOUS} command to the item
|
60
81
|
# @return [PlayerItem] `self`
|
82
|
+
|
83
|
+
# @!method previous!
|
84
|
+
# Send the {PREVIOUS} command to the item, even when
|
85
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
86
|
+
# @return [PlayerItem] `self`
|
61
87
|
end
|
62
88
|
end
|
63
89
|
end
|
@@ -41,18 +41,34 @@ module OpenHAB
|
|
41
41
|
# Send the {UP} command to the item
|
42
42
|
# @return [RollershutterItem] `self`
|
43
43
|
|
44
|
+
# @!method up!
|
45
|
+
# Send the {UP} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
46
|
+
# @return [RollershutterItem] `self`
|
47
|
+
|
44
48
|
# @!method down
|
45
49
|
# Send the {DOWN} command to the item
|
46
50
|
# @return [RollershutterItem] `self`
|
47
51
|
|
52
|
+
# @!method down!
|
53
|
+
# Send the {DOWN} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
54
|
+
# @return [RollershutterItem] `self`
|
55
|
+
|
48
56
|
# @!method stop
|
49
57
|
# Send the {STOP} command to the item
|
50
58
|
# @return [RollershutterItem] `self`
|
51
59
|
|
60
|
+
# @!method stop!
|
61
|
+
# Send the {STOP} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
62
|
+
# @return [RollershutterItem] `self`
|
63
|
+
|
52
64
|
# @!method move
|
53
65
|
# Send the {MOVE} command to the item
|
54
66
|
# @return [RollershutterItem] `self`
|
55
67
|
|
68
|
+
# @!method move!
|
69
|
+
# Send the {MOVE} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
70
|
+
# @return [RollershutterItem] `self`
|
71
|
+
|
56
72
|
# raw numbers translate directly to PercentType, not a DecimalType
|
57
73
|
# @!visibility private
|
58
74
|
def format_type(command)
|
@@ -101,6 +101,15 @@ module Enumerable
|
|
101
101
|
self if count { |i| i.command(command) }.positive?
|
102
102
|
end
|
103
103
|
|
104
|
+
# Send a command to every item in the collection, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
105
|
+
# @return [self]
|
106
|
+
def command!(command)
|
107
|
+
# We cannot alias this to #command above, otherwise it will call
|
108
|
+
# DSL::Items::Ensure::Item#command which checks for ensure_states
|
109
|
+
each { |i| i.command!(command) }
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
104
113
|
# Update the state of every item in the collection
|
105
114
|
# @return [self, nil] nil when `ensure` is in effect and all the items were already in the same state,
|
106
115
|
# otherwise self
|
@@ -108,6 +117,16 @@ module Enumerable
|
|
108
117
|
self if count { |i| i.update(state) }.positive?
|
109
118
|
end
|
110
119
|
|
120
|
+
# Update the state of every item in the collection, even when
|
121
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
122
|
+
# @return [self]
|
123
|
+
def update!(state)
|
124
|
+
# We cannot alias this to #update above, otherwise it will call
|
125
|
+
# DSL::Items::Ensure::Item#update which checks for ensure_states
|
126
|
+
each { |i| i.update!(state) }
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
111
130
|
# @!method refresh
|
112
131
|
# Send the {REFRESH} command to every item in the collection
|
113
132
|
# @return [self]
|
@@ -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,
|
@@ -67,9 +67,17 @@ module OpenHAB
|
|
67
67
|
# Send the {ON} command to the item
|
68
68
|
# @return [SwitchItem] `self`
|
69
69
|
|
70
|
+
# @!method on!
|
71
|
+
# Send the {ON} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
72
|
+
# @return [SwitchItem] `self`
|
73
|
+
|
70
74
|
# @!method off
|
71
75
|
# Send the {OFF} command to the item
|
72
76
|
# @return [SwitchItem] `self`
|
77
|
+
|
78
|
+
# @!method off!
|
79
|
+
# Send the {OFF} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
80
|
+
# @return [SwitchItem] `self`
|
73
81
|
end
|
74
82
|
end
|
75
83
|
end
|
data/lib/openhab/core/items.rb
CHANGED
@@ -65,13 +65,19 @@ module OpenHAB
|
|
65
65
|
ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def on(*args, &block)
|
66
66
|
command(#{value}, *args, &block) # command(ON, *args, &block)
|
67
67
|
end # end
|
68
|
+
ruby2_keywords def #{command}!(*args, &block) # ruby2_keywords def on!(*args, &block)
|
69
|
+
command!(#{value}, *args, &block) # command!(ON, *args, &block)
|
70
|
+
end # end
|
68
71
|
RUBY
|
69
72
|
|
70
73
|
logger.trace("Defining Enumerable##{command} for #{value}")
|
71
74
|
Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
72
|
-
def #{command}
|
73
|
-
each(&:#{command})
|
74
|
-
end
|
75
|
+
def #{command} # def on
|
76
|
+
each(&:#{command}) # each(&:on)
|
77
|
+
end # end
|
78
|
+
def #{command}! # def on!
|
79
|
+
each(&:#{command}!) # each(&:on!)
|
80
|
+
end # end
|
75
81
|
RUBY
|
76
82
|
|
77
83
|
logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
|
@@ -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
|
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
|
@@ -8,44 +8,38 @@ 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
|
-
|
16
|
+
def handle_command(command)
|
17
|
+
unless instance_variable_defined?(:@dummy_channel_item)
|
18
|
+
@dummy_channel_item = DSL::Items::ItemBuilder.item_factory.create_item(link.channel.accepted_item_type, "")
|
19
|
+
end
|
20
|
+
command = @dummy_channel_item.format_command(command) if @dummy_channel_item
|
21
|
+
super(command)
|
22
|
+
end
|
35
23
|
|
36
24
|
#
|
37
25
|
# Send a command to the framework.
|
38
26
|
#
|
39
27
|
# @param [Command] command
|
40
28
|
#
|
41
|
-
|
29
|
+
def send_command(command)
|
30
|
+
command = link.item.format_command(command)
|
31
|
+
super(command)
|
32
|
+
end
|
42
33
|
|
43
34
|
#
|
44
35
|
# Send a state update to the framework.
|
45
36
|
#
|
46
37
|
# @param [State] state
|
47
38
|
#
|
48
|
-
|
39
|
+
def send_update(state)
|
40
|
+
state = link.item.format_update(state)
|
41
|
+
super(state)
|
42
|
+
end
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -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
|
-
|
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
|
@@ -24,7 +24,7 @@ module OpenHAB
|
|
24
24
|
|
25
25
|
# Extensions for {::Item} to implement {Ensure}'s functionality
|
26
26
|
#
|
27
|
-
# @see OpenHAB::DSL
|
27
|
+
# @see OpenHAB::DSL::Items::Ensure::Ensurable#ensure ensure
|
28
28
|
# @see OpenHAB::DSL.ensure_states ensure_states
|
29
29
|
module Item
|
30
30
|
include Ensurable
|
@@ -210,7 +210,18 @@ module OpenHAB
|
|
210
210
|
thing_type,
|
211
211
|
self.class.config_description_registry
|
212
212
|
)
|
213
|
+
|
214
|
+
predefined_channels = self.class.thing_factory_helper
|
215
|
+
.create_channels(thing_type, uid, self.class.config_description_registry)
|
216
|
+
.to_h { |channel| [channel.uid, channel] }
|
217
|
+
new_channels = channels.to_h { |channel| [channel.uid, channel] }
|
218
|
+
merged_channels = predefined_channels.merge(new_channels) do |_key, predefined_channel, new_channel|
|
219
|
+
predefined_channel.configuration.merge!(new_channel.configuration)
|
220
|
+
predefined_channel
|
221
|
+
end
|
222
|
+
@channels = merged_channels.values
|
213
223
|
end
|
224
|
+
|
214
225
|
builder = org.openhab.core.thing.binding.builder.ThingBuilder
|
215
226
|
.create(thing_type_uid, uid)
|
216
227
|
.with_label(label)
|
@@ -219,15 +230,7 @@ module OpenHAB
|
|
219
230
|
.with_bridge(bridge_uid)
|
220
231
|
.with_channels(channels)
|
221
232
|
|
222
|
-
if thing_type
|
223
|
-
# can't use with_channels, or it will wipe out custom channels from above
|
224
|
-
self.class.thing_factory_helper.create_channels(thing_type,
|
225
|
-
uid,
|
226
|
-
self.class.config_description_registry).each do |channel|
|
227
|
-
builder.with_channel(channel)
|
228
|
-
end
|
229
|
-
builder.with_properties(thing_type.properties)
|
230
|
-
end
|
233
|
+
builder.with_properties(thing_type.properties) if thing_type
|
231
234
|
|
232
235
|
builder.build
|
233
236
|
end
|
@@ -263,8 +266,14 @@ module OpenHAB
|
|
263
266
|
:default_tags,
|
264
267
|
:properties,
|
265
268
|
:description,
|
266
|
-
:auto_update_policy
|
267
|
-
|
269
|
+
:auto_update_policy
|
270
|
+
|
271
|
+
class << self
|
272
|
+
# @!visibility private
|
273
|
+
def channel_type_registry
|
274
|
+
@channel_type_registry ||= OSGi.service("org.openhab.core.thing.type.ChannelTypeRegistry")
|
275
|
+
end
|
276
|
+
end
|
268
277
|
|
269
278
|
#
|
270
279
|
# Constructor for ChannelBuilder
|
@@ -284,7 +293,7 @@ module OpenHAB
|
|
284
293
|
# The default tags for this channel.
|
285
294
|
# @param [:default, :recommend, :veto, org.openhab.core.thing.type.AutoUpdatePolicy] auto_update_policy
|
286
295
|
# The channel's auto update policy.
|
287
|
-
# @param [String] accepted_item_type The accepted item type.
|
296
|
+
# @param [String] accepted_item_type The accepted item type. If nil, infer the item type from the channel type.
|
288
297
|
#
|
289
298
|
def initialize(uid,
|
290
299
|
type,
|
@@ -343,6 +352,12 @@ module OpenHAB
|
|
343
352
|
.build
|
344
353
|
end
|
345
354
|
|
355
|
+
# @!attribute [r] accepted_item_type
|
356
|
+
# @return [String] The accepted item type.
|
357
|
+
def accepted_item_type
|
358
|
+
@accepted_item_type ||= self.class.channel_type_registry.get_channel_type(type)&.item_type
|
359
|
+
end
|
360
|
+
|
346
361
|
private
|
347
362
|
|
348
363
|
def kind
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
@@ -557,10 +557,49 @@ module OpenHAB
|
|
557
557
|
# to reduce repetitions
|
558
558
|
#
|
559
559
|
|
560
|
+
#
|
561
|
+
# Permanently enable conditional execution of commands and updates for the current thread.
|
562
|
+
#
|
563
|
+
# When conditional executions are enabled, commands and updates will only be sent if the
|
564
|
+
# item's current state is not the same as the command or updated state.
|
565
|
+
# This eliminates the need to chain the command and update calls through
|
566
|
+
# {DSL::Items::Ensure::Ensurable#ensure ensure}.
|
567
|
+
#
|
568
|
+
# When conditional executions are enabled either by this method or within a block of {ensure_states},
|
569
|
+
# commands and updates can still be forcefully executed using the corresponding bang methods, e.g.
|
570
|
+
# `Item1.on!`, `Item1.command!(50)`, or `Item1.update!(ON)`.
|
571
|
+
#
|
572
|
+
# @note This method is only intended for use at the top level of rule
|
573
|
+
# scripts. If it's used within library methods, or hap-hazardly within
|
574
|
+
# rules, things can get very confusing because the prior state won't be
|
575
|
+
# properly restored.
|
576
|
+
#
|
577
|
+
# @param [Boolean] active Whether to enable or disable conditional executions.
|
578
|
+
# @return [Boolean] The previous ensure_states setting.
|
579
|
+
#
|
580
|
+
# @example Make ensure_states the default for the rest of the script
|
581
|
+
# ensure_states!
|
582
|
+
#
|
583
|
+
# # From now, all commands are "ensured", i.e. only sent when the current state is different
|
584
|
+
# Item1.on
|
585
|
+
# Item2.command(ON)
|
586
|
+
#
|
587
|
+
# # While ensure_states! is active, we can still forcibly send a command
|
588
|
+
# # regardless of the item's current state
|
589
|
+
# Item2.on!
|
590
|
+
#
|
591
|
+
# @see ensure_states
|
592
|
+
#
|
593
|
+
def ensure_states!(active: true)
|
594
|
+
old = Thread.current[:openhab_ensure_states]
|
595
|
+
Thread.current[:openhab_ensure_states] = active
|
596
|
+
old
|
597
|
+
end
|
598
|
+
|
560
599
|
#
|
561
600
|
# Global method that takes a block and for the duration of the block
|
562
601
|
# all commands sent will check if the item is in the command's state
|
563
|
-
# before sending the command.
|
602
|
+
# before sending the command. This also applies to updates.
|
564
603
|
#
|
565
604
|
# @yield
|
566
605
|
# @return [Object] The result of the block.
|
@@ -603,11 +642,10 @@ module OpenHAB
|
|
603
642
|
# end
|
604
643
|
#
|
605
644
|
def ensure_states
|
606
|
-
old =
|
607
|
-
Thread.current[:openhab_ensure_states] = true
|
645
|
+
old = ensure_states!
|
608
646
|
yield
|
609
647
|
ensure
|
610
|
-
|
648
|
+
ensure_states!(active: old)
|
611
649
|
end
|
612
650
|
|
613
651
|
#
|
@@ -841,7 +879,7 @@ module OpenHAB
|
|
841
879
|
# elements, the {Core::Items::Metadata::Hash} will be passed as an argument. Therefore it's
|
842
880
|
# recommended that you use a Proc, not a Lambda, for permissive argument matching.
|
843
881
|
#
|
844
|
-
# @return [
|
882
|
+
# @return [Hash] the prior provider configuration.
|
845
883
|
#
|
846
884
|
# @see provider
|
847
885
|
# @see OpenHAB::Core::Provider.current Provider.current for how the current provider is calculated
|
data/lib/openhab/rspec/shell.rb
CHANGED
@@ -5,26 +5,36 @@ module OpenHAB
|
|
5
5
|
# based on https://stackoverflow.com/questions/1197224/source-shell-script-into-environment-within-a-ruby-script#19826329
|
6
6
|
# @!visibility private
|
7
7
|
module Shell
|
8
|
-
|
8
|
+
# @!visibility private
|
9
|
+
DEFAULT_PRINTENV_COMMAND = "printenv -0"
|
10
|
+
@printenv_command = DEFAULT_PRINTENV_COMMAND
|
11
|
+
@printenv_separator = "\0"
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
cmd =
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
class << self
|
14
|
+
# Read in the bash environment, after an optional command.
|
15
|
+
# Returns Array of key/value pairs.
|
16
|
+
def shell_env(cmd = nil)
|
17
|
+
cmd = "#{cmd} > #{IO::NULL}; " if cmd
|
18
|
+
env = `#{cmd}#{@printenv_command} 2> #{IO::NULL}`
|
19
|
+
if !$?.success? && @printenv_command.equal?(DEFAULT_PRINTENV_COMMAND)
|
20
|
+
@printenv_command = "printenv"
|
21
|
+
@printenv_separator = "\n"
|
22
|
+
env = `#{cmd}#{@printenv_command}`
|
23
|
+
end
|
24
|
+
env.split(@printenv_separator).map { |l| l.split("=", 2) }
|
25
|
+
end
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
27
|
+
# Source a given file, and compare environment before and after.
|
28
|
+
# Returns Hash of any keys that have changed.
|
29
|
+
def shell_source(file)
|
30
|
+
(shell_env(". #{File.realpath(file)}") - shell_env).to_h
|
31
|
+
end
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
# Find variables changed as a result of sourcing the given file,
|
34
|
+
# and update in ENV.
|
35
|
+
def source_env_from(file)
|
36
|
+
shell_source(file).each { |k, v| ENV[k] = v }
|
37
|
+
end
|
28
38
|
end
|
29
39
|
end
|
30
40
|
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.
|
4
|
+
version: 5.11.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-
|
13
|
+
date: 2023-10-29 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
|