openhab-scripting 5.10.0 → 5.12.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: acf8ae7ed285c32bb11070e6ae64c54b9687dae7883c272be4a9ad30f399ed8c
4
- data.tar.gz: 8820ac3849f07734843d2863ff483fbde70bfe56c41981f2d48ec2e8c7bd73a8
3
+ metadata.gz: 35d0d28ba4dd272f12cd989761c2d615836d25dbafbc2af2b60692f8a535d5c1
4
+ data.tar.gz: 4d51dd07a43f5ff7a7ad43bc66cbb1d63b320486a82036d1a8cbfb22412a061b
5
5
  SHA512:
6
- metadata.gz: ab2e153c20c4d81b4b4b5b7d3025d1f49812099ea1040eba85b03f6fc8ce4217d84a3204e1c0917ed53c8386220b25da7d1da4bc367b51459ef74d67a52d7d44
7
- data.tar.gz: 0bdc096799e02f344f7d24c218af6ed045840c9a87ab890e81a339896801c53c6e18a6dabafd060e2c18023b69da8fdb4df9d3d58fcab3917baba6274fe992eb
6
+ metadata.gz: 76c075f22df43c0ecfe37775e297f496d2f55fe60e6da95bbece311d92fe3e37e50d867a23f6f52c3ebeb690771e7eb5512c357ca3b0745d83d03a8df892cad7
7
+ data.tar.gz: 93eb532732729b91437a669fbbe9b0b024397332faa435c82ebe17d50c4ea4a29576108c819010c0a497a5912d74eaa95e87fc0d98b01f9fa0987fbb52b5fa7b
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Events
6
+ java_import org.openhab.core.thing.events.ChannelTriggeredEvent
7
+
8
+ #
9
+ # {AbstractEvent} sent when a channel triggers.
10
+ #
11
+ class ChannelTriggeredEvent < AbstractEvent
12
+ extend Forwardable
13
+
14
+ # @!attribute [r] channel_uid
15
+ # @return [Things::ChannelUID] The UID of the {Things::Channel Channel} that triggered this event.
16
+ alias_method :channel_uid, :get_channel
17
+
18
+ # @!attribute [r] channel
19
+ # @return [Things::Channel, nil] The channel that triggered this event.
20
+
21
+ # @!attribute [r] thing
22
+ # @return [Things::Thing, nil] The thing that triggered this event.
23
+ def_delegators :channel_uid, :thing, :channel
24
+
25
+ # @!attribute [r] event
26
+ # @return [String] The event data
27
+ end
28
+ end
29
+ end
30
+ end
@@ -5,17 +5,18 @@ require_relative "item_state_event"
5
5
  module OpenHAB
6
6
  module Core
7
7
  module Events
8
- begin
8
+ # @deprecated OH3.4 if guard only needed in OH 3.4
9
+ if Gem::Version.new(OpenHAB::Core::VERSION) >= Gem::Version.new("4.0.0")
9
10
  java_import org.openhab.core.items.events.ItemStateUpdatedEvent
10
11
 
11
12
  #
12
13
  # {AbstractEvent} sent when an item's state has updated.
13
14
  #
15
+ # @since openHAB 4.0
16
+ #
14
17
  class ItemStateUpdatedEvent < ItemEvent
15
18
  include ItemState
16
19
  end
17
- rescue NameError
18
- # @deprecated OH3.4 OH3 will raise an error ItemStateUpdatedEvent is only in OH4
19
20
  end
20
21
  end
21
22
  end
@@ -102,7 +102,7 @@ module OpenHAB
102
102
  #
103
103
  def dim(amount = 1)
104
104
  target = [state&.-(amount), 0].compact.max
105
- command(target)
105
+ command!(target)
106
106
  target
107
107
  end
108
108
 
@@ -121,7 +121,7 @@ module OpenHAB
121
121
  #
122
122
  def brighten(amount = 1)
123
123
  target = [state&.+(amount), 100].compact.min
124
- command(target)
124
+ command!(target)
125
125
  target
126
126
  end
127
127
 
@@ -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,18 +39,35 @@ 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`
@@ -41,10 +41,18 @@ 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`
@@ -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]
@@ -50,9 +50,9 @@ module OpenHAB
50
50
  # @return [self]
51
51
  #
52
52
  def toggle
53
- return on unless state?
53
+ return on! unless state?
54
54
 
55
- command(!state)
55
+ command!(!state)
56
56
  end
57
57
 
58
58
  # @!method on?
@@ -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
@@ -60,19 +60,43 @@ module OpenHAB
60
60
  command = Types::COMMAND_ALIASES[value.to_s]
61
61
  next if klass.instance_methods.include?(command)
62
62
 
63
- logger.trace("Defining #{klass}##{command} for #{value}")
64
- klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
65
- ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def on(*args, &block)
66
- command(#{value}, *args, &block) # command(ON, *args, &block)
67
- end # end
68
- RUBY
63
+ if value.is_a?(Types::State)
64
+ logger.trace("Defining #{klass}/Enumerable##{command}/#{command}! for #{value}")
69
65
 
70
- logger.trace("Defining Enumerable##{command} for #{value}")
71
- Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
72
- def #{command} # def on
73
- each(&:#{command}) # each(&:on)
74
- end # end
75
- RUBY
66
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
67
+ ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def on(*args, &block)
68
+ command(#{value}, *args, &block) # command(ON, *args, &block)
69
+ end # end
70
+ #
71
+ ruby2_keywords def #{command}!(*args, &block) # ruby2_keywords def on!(*args, &block)
72
+ command!(#{value}, *args, &block) # command!(ON, *args, &block)
73
+ end # end
74
+ RUBY
75
+
76
+ Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
77
+ def #{command} # def on
78
+ each(&:#{command}) # each(&:on)
79
+ end # end
80
+ #
81
+ def #{command}! # def on!
82
+ each(&:#{command}!) # each(&:on!)
83
+ end # end
84
+ RUBY
85
+ else
86
+ logger.trace("Defining #{klass}/Enumerable##{command} for #{value}")
87
+
88
+ klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
89
+ ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def refresh(*args, &block)
90
+ command!(#{value}, *args, &block) # command!(REFRESH, *args, &block)
91
+ end # end
92
+ RUBY
93
+
94
+ Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
95
+ def #{command} # def refresh
96
+ each(&:#{command}) # each(&:refresh)
97
+ end # end
98
+ RUBY
99
+ end
76
100
 
77
101
  logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
78
102
  Events::ItemCommandEvent.class_eval <<~RUBY, __FILE__, __LINE__ + 1
@@ -6,12 +6,14 @@ require_relative "script_handling"
6
6
 
7
7
  module OpenHAB
8
8
  module Core
9
+ # rubocop:disable Naming/MethodName
9
10
  # @!visibility private
10
11
  class ProfileFactory
12
+ include org.openhab.core.config.core.ConfigDescriptionProvider # This needs to be included first
11
13
  include org.openhab.core.thing.profiles.ProfileFactory
14
+ include org.openhab.core.thing.profiles.ProfileTypeProvider
12
15
  include Singleton
13
16
 
14
- # rubocop:disable Naming/MethodName
15
17
  class Profile
16
18
  include org.openhab.core.thing.profiles.StateProfile
17
19
 
@@ -96,10 +98,10 @@ module OpenHAB
96
98
  end
97
99
  end
98
100
  private_constant :Profile
99
- # rubocop:enable Naming/MethodName
100
101
 
101
102
  def initialize
102
103
  @profiles = {}
104
+ @uri_to_uid = {}
103
105
 
104
106
  @registration = OSGi.register_service(self)
105
107
  ScriptHandling.script_unloaded { unregister }
@@ -116,17 +118,56 @@ module OpenHAB
116
118
  end
117
119
 
118
120
  # @!visibility private
119
- def register(uid, block)
120
- @profiles[uid] = [DSL::ThreadLocal.persist, block]
121
+ def register(id, block, label: nil, config_description: nil)
122
+ uid = org.openhab.core.thing.profiles.ProfileTypeUID.new("ruby", id)
123
+ uri = java.net.URI.new("profile", uid.to_s, nil)
124
+ if config_description && config_description.uid != uri
125
+ config_description = org.openhab.core.config.core.ConfigDescriptionBuilder.create(uri)
126
+ .with_parameters(config_description.parameters)
127
+ .with_parameter_groups(config_description.parameter_groups)
128
+ .build
129
+ end
130
+
131
+ @profiles[uid] = {
132
+ thread_locals: DSL::ThreadLocal.persist,
133
+ label: label,
134
+ config_description: config_description,
135
+ block: block
136
+ }
137
+ @uri_to_uid[uri] = uid
121
138
  end
122
139
 
123
- def createProfile(type, callback, context) # rubocop:disable Naming/MethodName
124
- @profiles[type].then { |(thread_locals, block)| Profile.new(callback, context, type, thread_locals, block) }
140
+ # @!visibility private
141
+ def createProfile(uid, callback, context)
142
+ profile = @profiles[uid]
143
+ Profile.new(callback, context, uid, profile[:thread_locals], profile[:block])
125
144
  end
126
145
 
127
- def getSupportedProfileTypeUIDs # rubocop:disable Naming/MethodName
146
+ # @!visibility private
147
+ def getSupportedProfileTypeUIDs
128
148
  @profiles.keys
129
149
  end
150
+
151
+ # @!visibility private
152
+ def getProfileTypes(_locale)
153
+ @profiles.map do |uid, profile|
154
+ next if profile[:label].nil?
155
+
156
+ org.openhab.core.thing.profiles.ProfileTypeBuilder.new_state(uid, "RUBY #{profile[:label]}").build
157
+ end.compact
158
+ end
159
+
160
+ # @!visibility private
161
+ def getConfigDescriptions(_locale)
162
+ @profiles.values.map { |profile| profile[:config_description] if profile[:label] }.compact
163
+ end
164
+
165
+ # @!visibility private
166
+ def getConfigDescription(uri, _locale)
167
+ uid = @uri_to_uid[uri]
168
+ @profiles.dig(uid, :config_description)
169
+ end
130
170
  end
171
+ # rubocop:enable Naming/MethodName
131
172
  end
132
173
  end
@@ -70,13 +70,17 @@ module OpenHAB
70
70
  # text label: "Climate", icon: "if:mdi:home-thermometer-outline" do
71
71
  # frame label: "Main Floor" do
72
72
  # text item: MainFloor_AmbTemp
73
- # switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat]
73
+ # # colors are set with a hash, with key being condition, and value being the color
74
+ # switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat], label_color: { "==heat" => "red", "" => "black" }
75
+ # # an array of conditions are OR'd together
76
+ # switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat], label_color: { ["==heat", "==cool"], => "green" }
74
77
  # setpoint item: MainFloorThermostat_SetPoint, label: "Set Point", visibility: "MainFloorThermostat_TargetMode!=off"
75
78
  # end
76
79
  # frame label: "Basement" do
77
80
  # text item: Basement_AmbTemp
78
81
  # switch item: BasementThermostat_TargetMode, label: "Mode", mappings: { OFF: "off", COOL: "cool", HEAT: "heat" }
79
- # setpoint item: BasementThermostat_SetPoint, label: "Set Point", visibility: "BasementThermostat_TargetMode!=off"
82
+ # # nested arrays are conditions that are AND'd together, instead of OR'd (requires openHAB 4.1)
83
+ # setpoint item: BasementThermostat_SetPoint, label: "Set Point", visibility: [["BasementThermostat_TargetMode!=off", "Vacation_Switch!=OFF"]]
80
84
  # end
81
85
  # end
82
86
  # end
@@ -22,6 +22,16 @@ module OpenHAB
22
22
  EntityLookup.lookup_thing(thing_uid)
23
23
  end
24
24
 
25
+ # @attribute [r] channel
26
+ #
27
+ # Return the channel object for this channel
28
+ #
29
+ # @return [Channel, nil]
30
+ #
31
+ def channel
32
+ thing.channels[self]
33
+ end
34
+
25
35
  #
26
36
  # @attribute [r] item
27
37
  #
@@ -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
 
@@ -72,6 +72,7 @@ module OpenHAB
72
72
  # Allows indexing by both integer as an array or channel id acting like a hash.
73
73
  # @param [Integer, String, ChannelUID] index
74
74
  # Numeric index, string channel id, or a {ChannelUID} to search for.
75
+ # @return [Channel, nil]
75
76
  def [](index)
76
77
  return @thing.get_channel(index) if index.is_a?(ChannelUID)
77
78
  return @thing.get_channel(index.to_str) if index.respond_to?(:to_str)
@@ -70,7 +70,7 @@ module OpenHAB
70
70
  #
71
71
  # Convert DecimalType to a QuantityType
72
72
  #
73
- # @param [String, javax.measure.units.Unit] other
73
+ # @param [String, javax.measure.Unit] other
74
74
  #
75
75
  # @return [QuantityType] `self` as a {QuantityType} of the supplied Unit
76
76
  #
@@ -106,7 +106,7 @@ module OpenHAB
106
106
  # #
107
107
  # # Convert this {QuantityType} into another unit.
108
108
  # #
109
- # # @param [String, javax.measure.units.Unit] unit
109
+ # # @param [String, javax.measure.Unit] unit
110
110
  # # @return [QuantityType]
111
111
  # #
112
112
  # # @example
@@ -287,7 +287,7 @@ module OpenHAB
287
287
  end
288
288
  end
289
289
 
290
- # if unit is {org.openhab.core.library.unit.Units.ONE}, return a plain
290
+ # if unit is {org.openhab.core.library.unit.Units::ONE}, return a plain
291
291
  # Java BigDecimal
292
292
  # @!visibility private
293
293
  def deunitize
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ #
6
+ # Contains the DSL for creating {org.openhab.core.config.core.ConfigDescription} instances.
7
+ #
8
+ module ConfigDescription
9
+ #
10
+ # A ConfigDescriptionBuilder is used to create a {org.openhab.core.config.core.ConfigDescription}
11
+ # instance.
12
+ #
13
+ # @see DSL.config_description config_description
14
+ #
15
+ class Builder
16
+ def initialize
17
+ @parameters = []
18
+ @parameter_groups = []
19
+ @current_group = nil
20
+ end
21
+
22
+ #
23
+ # Create a parameter group.
24
+ #
25
+ # @param [String, Symbol] name The group name. This name will be referred to by {parameter}.
26
+ # @param [String, nil] label The group label
27
+ # @param [String, nil] description The group description
28
+ # @param [Boolean] advanced Whether the group is advanced
29
+ # @param [<Type>] context Context for the group
30
+ #
31
+ # @yield Block executed in the context of this group. Any {parameter} calls within the block will
32
+ # automatically be added to this group, unless it specifies a different group name.
33
+ #
34
+ # @return [void]
35
+ #
36
+ def group(name, label: nil, description: nil, advanced: false, context: nil, &block)
37
+ raise ArgumentError, "Groups cannot be nested" if @current_group
38
+
39
+ name = name.to_s
40
+ @parameter_groups << org.openhab.core.config.core.ConfigDescriptionParameterGroupBuilder
41
+ .create(name)
42
+ .with_label(label)
43
+ .with_description(description)
44
+ .with_advanced(advanced)
45
+ .with_context(context)
46
+ .build
47
+
48
+ @current_group = name
49
+ instance_eval(&block) if block
50
+ ensure
51
+ @current_group = nil
52
+ end
53
+
54
+ #
55
+ # Adds a parameter to the config description.
56
+ #
57
+ # @param [String, Symbol] name Parameter name
58
+ # @param [:text, :integer, :decimal, :boolean] type
59
+ # Parameter type. See {org.openhab.core.config.core.ConfigDescriptionParameter.Type}
60
+ # @param [String, nil] label Parameter label
61
+ # @param [String, nil] description Parameter description
62
+ # @param [Numeric, nil] min Minimum value for numeric types
63
+ # @param [Numeric, nil] max Maximum value for numeric types
64
+ # @param [Numeric, nil] step Step size for numeric types
65
+ # @param [String, nil] pattern Regular expression pattern for string types
66
+ # @param [true, false] required Whether the parameter is required
67
+ # @param [true, false] read_only Whether the parameter is read only
68
+ # @param [true, false] multiple Whether the parameter is a list of values
69
+ # @param [String, nil] context Context for the parameter
70
+ # @param [Object, nil] default Default value for the parameter
71
+ # @param [Hash] options Options for the parameter
72
+ # @param [Hash] filter_criteria Filter criteria for the parameter
73
+ # @param [String, nil] group_name Parameter group name.
74
+ # When nil, it will be inferred when this method is called inside a {group} block.
75
+ # @param [true, false] advanced Whether the parameter is advanced
76
+ # @param [true, false] limit_to_options Whether the parameter is limited to the given options
77
+ # @param [Integer, nil] multiple_limit Maximum number of values for a multiple parameter
78
+ # @param [String, nil] unit Parameter unit
79
+ # @param [String, nil] unit_label Parameter unit label
80
+ # @param [true, false] verify Whether the parameter value should be verified
81
+ #
82
+ # @return [void]
83
+ #
84
+ # @see org.openhab.core.config.core.ConfigDescriptionParameter
85
+ #
86
+ def parameter(name,
87
+ type,
88
+ label: nil,
89
+ description: nil,
90
+ min: nil,
91
+ max: nil,
92
+ step: nil,
93
+ pattern: nil,
94
+ required: false,
95
+ read_only: false,
96
+ multiple: false,
97
+ context: nil,
98
+ default: nil,
99
+ options: {},
100
+ filter_criteria: {},
101
+ group_name: nil,
102
+ advanced: false,
103
+ limit_to_options: false,
104
+ multiple_limit: nil,
105
+ unit: nil,
106
+ unit_label: nil,
107
+ verify: false)
108
+ # Extract the named arguments into a hash
109
+ @parameters << method(__method__).parameters
110
+ .select { |param_type, _| param_type == :key }
111
+ .to_h { |_, key| [key, binding.local_variable_get(key)] }
112
+ .then do |p|
113
+ p[:options] = p[:options].map do |opt_value, opt_label|
114
+ org.openhab.core.config.core.ParameterOption.new(opt_value, opt_label)
115
+ end
116
+ p[:filter_criteria] = p[:filter_criteria].map do |filter_name, filter_value|
117
+ org.openhab.core.config.core.FilterCriteria.new(filter_name, filter_value)
118
+ end
119
+ p[:minimum] = p.delete(:min)&.to_d&.to_java
120
+ p[:maximum] = p.delete(:max)&.to_d&.to_java
121
+ p[:step] = p.delete(:step)&.to_d&.to_java
122
+ p[:group_name] ||= @current_group
123
+ type = org.openhab.core.config.core.ConfigDescriptionParameter::Type.value_of(type.to_s.upcase)
124
+
125
+ parameter = org.openhab.core.config.core.ConfigDescriptionParameterBuilder.create(name.to_s, type)
126
+
127
+ p.each do |key, value|
128
+ parameter.send("with_#{key}", value) unless value.nil?
129
+ end
130
+ parameter.build
131
+ end
132
+ end
133
+
134
+ #
135
+ # Build the config description
136
+ #
137
+ # @param [String, java.net.URI] uri The URI for the config description. When nil, it will default to `dummy:uri`
138
+ # @yield Block executed in the context of this builder. Inside the block, you can call {parameter} and {group}.
139
+ #
140
+ # @return [org.openhab.core.config.core.ConfigDescription] The created ConfigDescription object
141
+ #
142
+ def build(uri = nil, &block)
143
+ instance_eval(&block) if block
144
+ raise ArgumentError, "No parameters defined" if @parameters.empty?
145
+
146
+ uri ||= "dummy:uri"
147
+ uri = java.net.URI.new(uri.to_s) unless uri.is_a?(java.net.URI)
148
+ org.openhab.core.config.core.ConfigDescriptionBuilder
149
+ .create(uri)
150
+ .with_parameters(@parameters)
151
+ .with_parameter_groups(@parameter_groups)
152
+ .build
153
+ end
154
+ end
155
+ end
156
+ end
157
+ 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.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
@@ -36,6 +36,8 @@ module OpenHAB
36
36
  # sending the command
37
37
  %i[command update].each do |ensured_method|
38
38
  # def command(state)
39
+ # # immediately send the command if it's a command, but not a state (like REFRESH)
40
+ # return super(state) if state.is_a?(Command) && !state.is_a?(State)
39
41
  # return super(state) unless Thread.current[:openhab_ensure_states]
40
42
  #
41
43
  # formatted_state = format_command(state)
@@ -48,6 +50,8 @@ module OpenHAB
48
50
  # end
49
51
  class_eval <<~RUBY, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
50
52
  def #{ensured_method}(state)
53
+ # immediately send the command if it's a command, but not a state (like REFRESH)
54
+ #{"return super(state) if state.is_a?(Command) && !state.is_a?(State)" if ensured_method == :command}
51
55
  return super(state) unless Thread.current[:openhab_ensure_states]
52
56
 
53
57
  formatted_state = format_#{ensured_method}(state)