openhab-scripting 5.10.0 → 5.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acf8ae7ed285c32bb11070e6ae64c54b9687dae7883c272be4a9ad30f399ed8c
4
- data.tar.gz: 8820ac3849f07734843d2863ff483fbde70bfe56c41981f2d48ec2e8c7bd73a8
3
+ metadata.gz: 9e7d078cc73659d0f435950d36438b67759b2e3b5c0abf80f258a36101792a0d
4
+ data.tar.gz: 2a76c20015d6320b64a2a9ea79557c7133b1101a8514fabba9241f91b455615d
5
5
  SHA512:
6
- metadata.gz: ab2e153c20c4d81b4b4b5b7d3025d1f49812099ea1040eba85b03f6fc8ce4217d84a3204e1c0917ed53c8386220b25da7d1da4bc367b51459ef74d67a52d7d44
7
- data.tar.gz: 0bdc096799e02f344f7d24c218af6ed045840c9a87ab890e81a339896801c53c6e18a6dabafd060e2c18023b69da8fdb4df9d3d58fcab3917baba6274fe992eb
6
+ metadata.gz: bc54b1fae7be3bee15b1af2c27526cf942a13741404dd1c0e61034b82d2d472703bfb48ef921d25ed608dbe3d9c964abbded85ab1d3adfd855847229c6bf2447
7
+ data.tar.gz: c454623c911c90be03464391f885b8ccebfd2789b5e9dbbe32a6f8309fdf7e1f948e2c0730373d383bf7892271ab752bf9d8c2197ed541cff7f33a692ea296ec
@@ -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)
@@ -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]
@@ -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
@@ -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} # def on
73
- each(&:#{command}) # each(&:on)
74
- end # 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}")
@@ -14,9 +14,10 @@ module OpenHAB
14
14
  # @param [Command] command
15
15
  #
16
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)
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
20
21
  super(command)
21
22
  end
22
23
 
@@ -24,7 +24,7 @@ module OpenHAB
24
24
 
25
25
  # Extensions for {::Item} to implement {Ensure}'s functionality
26
26
  #
27
- # @see OpenHAB::DSL.ensure ensure
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
- :accepted_item_type
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
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.10.0"
7
+ VERSION = "5.11.0"
8
8
  end
9
9
  end
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 = Thread.current[:openhab_ensure_states]
607
- Thread.current[:openhab_ensure_states] = true
645
+ old = ensure_states!
608
646
  yield
609
647
  ensure
610
- Thread.current[:openhab_ensure_states] = old
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 [void]
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
@@ -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
- module_function
8
+ # @!visibility private
9
+ DEFAULT_PRINTENV_COMMAND = "printenv -0"
10
+ @printenv_command = DEFAULT_PRINTENV_COMMAND
11
+ @printenv_separator = "\0"
9
12
 
10
- # Read in the bash environment, after an optional command.
11
- # Returns Array of key/value pairs.
12
- def shell_env(cmd = nil)
13
- cmd = "#{cmd} > /dev/null; " if cmd
14
- env = `#{cmd}printenv -0`
15
- env.split("\0").map { |l| l.split("=", 2) }
16
- end
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
- # Source a given file, and compare environment before and after.
19
- # Returns Hash of any keys that have changed.
20
- def shell_source(file)
21
- (shell_env(". #{File.realpath(file)}") - shell_env).to_h
22
- end
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
- # Find variables changed as a result of sourcing the given file,
25
- # and update in ENV.
26
- def source_env_from(file)
27
- shell_source(file).each { |k, v| ENV[k] = v }
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.10.0
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-25 00:00:00.000000000 Z
13
+ date: 2023-10-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler