openhab-scripting 5.10.0 → 5.12.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: 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)