Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add all state and command descriptions options to items builder #351

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
66 changes: 66 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,72 @@ 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) if RUBY_VERSION >= "2.7"
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
if RUBY_VERSION >= "2.7"
expect(Number3.state_description.minimum).to be_nil
expect(Number3.state_description.maximum.to_i).to be 50
end
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