openhab-scripting 5.9.0 → 5.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|