Skip to content

Commit

Permalink
Allow updating things/items/sitemaps by recreating them
Browse files Browse the repository at this point in the history
Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng committed Sep 21, 2023
1 parent 45cf096 commit 5acf7df
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 17 deletions.
6 changes: 4 additions & 2 deletions lib/openhab/core/items/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ def to_a
# Enter the Item Builder DSL.
#
# @param (see Core::Provider.current)
# @param [true, false] replace_existing Replace existing items with the same name.
# @yield Block executed in the context of a {DSL::Items::Builder}
# @return [Object] The return value of the block.
#
# @see DSL::Items::Builder
#
def build(preferred_provider = nil, &block)
DSL::Items::BaseBuilderDSL.new(preferred_provider).instance_eval_with_dummy_items(&block)
def build(preferred_provider = nil, replace_existing: false, &block)
DSL::Items::BaseBuilderDSL.new(preferred_provider, replace_existing: replace_existing)
.instance_eval_with_dummy_items(&block)
end

#
Expand Down
10 changes: 6 additions & 4 deletions lib/openhab/core/sitemaps/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ def unregister
# end
# end
#
def build(&block)
DSL::Sitemaps::Builder.new(self).instance_eval(&block)
def build(replace_existing: false, &block)
DSL::Sitemaps::Builder.new(self, replace_existing: replace_existing).instance_eval(&block)
end
# rubocop:enable Layout/LineLength

Expand Down Expand Up @@ -123,8 +123,10 @@ def notify_listeners_about_removed_element(element)
@listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::REMOVED) }
end

def notify_listeners_about_updated_element(element)
@listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::MODIFIED) }
def notify_listeners_about_updated_element(_old_element, element)
@listeners.each do |l|
l.model_changed(element.name, org.openhab.core.model.core.EventType::MODIFIED)
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/openhab/core/things/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def to_a
# @yield Block executed in the context of a {DSL::Things::Builder}.
# @return [Object] The result of the block.
#
def build(preferred_provider = nil, &block)
DSL::Things::Builder.new(preferred_provider).instance_eval(&block)
def build(preferred_provider = nil, replace_existing: false, &block)
DSL::Things::Builder.new(preferred_provider, replace_existing: replace_existing).instance_eval(&block)
end

#
Expand Down
13 changes: 9 additions & 4 deletions lib/openhab/dsl/items/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,19 @@ class BaseBuilderDSL
class ProviderWrapper
attr_reader :provider

def initialize(provider)
def initialize(provider, replace_existing:)
@provider = provider
@replace_existing = replace_existing
end

# @!visibility private
def add(builder)
item = builder.build
provider.add(item)
if @replace_existing && provider[item.uid]
provider.update(item)
else
provider.add(item)
end
# make sure to add the item to the registry before linking it
builder.channels.each do |(channel, config)|
if !channel.include?(":") &&
Expand All @@ -143,8 +148,8 @@ def add(builder)
# @return [org.openhab.core.items.ItemProvider]
attr_reader :provider

def initialize(provider)
@provider = ProviderWrapper.new(Core::Items::Provider.current(provider))
def initialize(provider, replace_existing:)
@provider = ProviderWrapper.new(Core::Items::Provider.current(provider), replace_existing: replace_existing)
end
end

Expand Down
11 changes: 8 additions & 3 deletions lib/openhab/dsl/sitemaps/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ module Sitemaps
# Base sitemap builder DSL
class Builder
# @!visibility private
def initialize(provider)
def initialize(provider, replace_existing:)
@provider = provider
@replace_existing = replace_existing
end

# (see SitemapBuilder#initialize)
Expand All @@ -23,8 +24,12 @@ def initialize(provider)
def sitemap(name, label = nil, icon: nil, &block)
sitemap = SitemapBuilder.new(name, label, icon: icon)
sitemap.instance_eval_with_dummy_items(&block) if block
@provider.add(sitemap.build)
sitemap
sitemap = sitemap.build
if @replace_existing && @provider[sitemap.uid]
@provider.update(sitemap)
else
@provider.add(sitemap)
end
end
end

Expand Down
10 changes: 8 additions & 2 deletions lib/openhab/dsl/things/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ class Builder
# @return [org.openhab.core.thing.ManagedThingProvider]
attr_reader :provider

def initialize(provider)
def initialize(provider, replace_existing: false)
@provider = Core::Things::Provider.current(provider)
@replace_existing = replace_existing
end

# Create a new Bridge
Expand All @@ -61,7 +62,12 @@ def thing(*args, **kwargs, &block)
def build(klass, *args, **kwargs, &block)
builder = klass.new(*args, **kwargs)
builder.instance_eval(&block) if block
thing = provider.add(builder.build)
thing = builder.build
if @replace_existing && provider[thing.uid]
provider.update(thing)
else
provider.add(thing)
end
thing = Core::Things::Proxy.new(thing)
thing.enable(enabled: builder.enabled) unless builder.enabled.nil?
thing
Expand Down
6 changes: 6 additions & 0 deletions spec/openhab/dsl/items/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
expect { items.build { switch_item "Switch1" } }.to raise_error(ArgumentError)
end

it "can replace existing items with replace_existing option" do
items.build { switch_item "ReplacedItem", "Old Label" }
items.build(replace_existing: true) { switch_item "ReplacedItem", "New Label" }
expect(ReplacedItem.label).to eql "New Label"
end

it "can remove an item" do
items.build { switch_item "MySwitchItem", autoupdate: false, channel: "binding:type:thing:channel" }
items.remove(MySwitchItem)
Expand Down
12 changes: 12 additions & 0 deletions spec/openhab/dsl/sitemaps/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,16 @@
end
end
end

context "when redefining a sitemap" do
it "complains if you try to create a sitemap with the same name" do
sitemaps.build { sitemap "default" }
expect { sitemaps.build { sitemap "default" } }.to raise_error(ArgumentError)
end

it "allows you to redefine a sitemap with the same name if replace_existing: true" do
sitemaps.build { sitemap "default" }
sitemaps.build(replace_existing: true) { sitemap "default" }
end
end
end
37 changes: 37 additions & 0 deletions spec/openhab/dsl/things/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@
expect(home.configuration.get("geolocation")).to eq "0,0"
end

it "complains if you try to create a thing with the same UID" do
uid = "a:b:c"
things.build { thing uid }
expect { things.build { thing uid } }.to raise_error(ArgumentError)
end

context "with replace_existing: true" do
it "existing things are replaced" do
uid = "replace:existing:thing"
things.build { thing uid, "Old Label" }
expect(things[uid].label).to eql "Old Label"
things.build(replace_existing: true) { thing uid, "New Label" }
expect(things[uid].label).to eql "New Label"
end

it "existing items are relinked" do
uid = "a:b:c"
thing = things.build do
thing uid, "old thing" do
channel "d", "string"
end
end

items.build { string_item "String1", thing: thing, channel: "d" }

expect(String1.thing.label).to eql "old thing"

thing = things.build(replace_existing: true) do
thing uid, "new thing" do
channel "d", "string"
end
end

expect(String1.thing.label).to eql "new thing"
end
end

it "can create a thing with separate binding and type params" do
things.build do
thing "home", "Astro Sun Data", binding: "astro", type: "sun"
Expand Down

0 comments on commit 5acf7df

Please sign in to comment.