Skip to content

Commit

Permalink
Add allow state and command descriptions options to items builder
Browse files Browse the repository at this point in the history
Signed-off-by: Cody Cutrer <[email protected]>
  • Loading branch information
ccutrer committed Oct 4, 2024
1 parent ce5c328 commit 40ef244
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 1 deletion.
58 changes: 57 additions & 1 deletion lib/openhab/dsl/items/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,24 @@ class ItemBuilder
#
# @return [String, nil]
attr_accessor :format
# The valid range for a number item
# @return [Range, nil]
attr_accessor :range
# The step size for a number item
# @return [Number, nil]
attr_accessor :step
# If the item is read-only, and does not accept commands
# @return [true, false, nil]
attr_accessor :read_only
alias_method :read_only?, :read_only
# A list of valid commands
# If a hash, keys are commands, and values are labels
# @return [Hash, Array, nil]
attr_accessor :command_options
# A list of valid states
# If a hash, keys are commands, and values are labels
# @return [Hash, Array, nil]
attr_accessor :state_options
# The icon to be associated with the item
# @return [Symbol, String, nil]
attr_accessor :icon
Expand Down Expand Up @@ -321,6 +339,11 @@ def initialize(type,
dimension: nil,
unit: nil,
format: nil,
range: nil,
step: nil,
read_only: nil,
command_options: nil,
state_options: nil,
icon: nil,
group: nil,
groups: nil,
Expand Down Expand Up @@ -358,6 +381,11 @@ def initialize(type,
@label = label
@dimension = dimension
@format = format
@range = range
@step = step
@read_only = read_only
@command_options = command_options
@state_options = state_options
self.unit = unit
@icon = icon
@groups = []
Expand Down Expand Up @@ -591,7 +619,35 @@ def build
end
metadata["autoupdate"] = autoupdate.to_s unless autoupdate.nil?
metadata["expire"] = expire if expire
metadata["stateDescription"] = { "pattern" => format } if format
if format || range || step || !read_only.nil? || state_options
sd = {}
sd["pattern"] = format if format
sd["min"] = range.begin&.to_d if range&.begin
sd["max"] = range.end&.to_d if range&.end
sd["step"] = step if step
sd["readOnly"] = read_only unless read_only.nil?
if state_options
sd["options"] = if state_options.respond_to?(:to_hash)
state_options.to_hash.map { |k, v| "#{k}=#{v}" }.join(",")
elsif state_options.respond_to?(:to_ary)
state_options.to_ary.join(",")
else
state_options.to_s
end
end

metadata["stateDescription"] = sd
end
if command_options
options = if command_options.respond_to?(:to_hash)
command_options.to_hash.map { |k, v| "#{k}=#{v}" }.join(",")
elsif command_options.respond_to?(:to_ary)
command_options.to_ary.join(",")
else
command_options.to_s
end
metadata["commandDescription"] = { "options" => options }
end
metadata["unit"] = unit if unit
item
end
Expand Down
64 changes: 64 additions & 0 deletions spec/openhab/dsl/items/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,70 @@ def build_and_update(org_config, new_config, item_to_keep: :new_item, &block)
expect(MyNumberItem.state_description.pattern).to eql "something %d else"
end

it "can set a range on a number item" do
items.build do
number_item "Number1", range: 5..10
number_item "Number2", range: 2..10, step: 2
number_item "Number3", range: Range.new(nil, 50)
number_item "Number4", range: 50..
end

expect(Number1.state_description.minimum.to_i).to be 5
expect(Number1.state_description.maximum.to_i).to be 10
expect(Number1.state_description.step).to be_nil
expect(Number2.state_description.minimum.to_i).to be 2
expect(Number2.state_description.maximum.to_i).to be 10
expect(Number2.state_description.step.to_i).to be 2
expect(Number3.state_description.minimum).to be_nil
expect(Number3.state_description.maximum.to_i).to be 50
expect(Number4.state_description.minimum.to_i).to be 50
expect(Number4.state_description.maximum).to be_nil
end

it "can set read only" do
items.build do
switch_item "Switch1", read_only: true
switch_item "Switch2", read_only: false
switch_item "Switch3"
end

expect(Switch1.state_description).to be_read_only
expect(Switch2.state_description).not_to be_read_only
expect(Switch3.state_description).to be_nil
end

it "can set state options" do
items.build do
string_item "Text1", state_options: %w[LOCKED UNLOCKED]
switch_item "Lock1", state_options: { ON => "LOCKED", OFF => "UNLOCKED" }
end

expect(Text1.state_description.options.to_h { |o| [o.value, o.label] }).to eql({
"LOCKED" => nil,
"UNLOCKED" => nil
})
expect(Lock1.state_description.options.to_h { |o| [o.value, o.label] }).to eql({
"ON" => "LOCKED",
"OFF" => "UNLOCKED"
})
end

it "can set command options" do
items.build do
string_item "Text1", command_options: %w[LOCKED UNLOCKED]
switch_item "Lock1", command_options: { ON => "LOCKED", OFF => "UNLOCKED" }
end

expect(Text1.command_description.command_options.to_h { |o| [o.command, o.label] }).to eql({
"LOCKED" => nil,
"UNLOCKED" => nil
})
expect(Lock1.command_description.command_options.to_h { |o| [o.command, o.label] }).to eql({
"ON" => "LOCKED",
"OFF" => "UNLOCKED"
})
end

it "does not overwrite an explicit format with the unit" do
items.build do
number_item "MyNumberItem", format: "something %d else", unit: "W"
Expand Down

0 comments on commit 40ef244

Please sign in to comment.