Skip to content

Commit

Permalink
Sitemap Builder
Browse files Browse the repository at this point in the history
Signed-off-by: Cody Cutrer <cody@cutrer.us>
  • Loading branch information
ccutrer committed Sep 17, 2023
1 parent e98cab8 commit 4c73e6f
Show file tree
Hide file tree
Showing 8 changed files with 1,272 additions and 4 deletions.
5 changes: 3 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ Bundler/GemFilename:

Layout/LineLength:
AllowedPatterns:
- "# @example" # YARD example titles can't be broken up onto multiple lines.
- "# @see" # YARD example titles can't be broken up onto multiple lines.
- "# @!method" # Some YARD tags can't be broken up onto multiple ines
- "# @example"
- "# @see"
- "data:[a-z/]+;base64," # Base64 data is long

Lint/RescueException:
Expand Down
26 changes: 26 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ If you're new to Ruby, you may want to check out [Ruby Basics](docs/ruby-basics.
- [Shared Code](#shared-code)
- [Transformations](#transformations)
- [Profile](#profile)
- [Sitemaps](#sitemaps)
- [File Based Rules](#file-based-rules)
- [Basic Rule Structure](#basic-rule-structure)
- [Rule Triggers](#rule-triggers)
Expand Down Expand Up @@ -1378,6 +1379,31 @@ When the item contains `0 °C`, this will produce a formatted state of `0 °C /
You can create an openHAB profile in JRuby that can be applied to item channel links.
For more details, see {OpenHAB::DSL.profile #profile}.

### Sitemaps

Sitemaps can be created via {OpenHAB::Core::Sitemaps::Provider#build sitemaps.build}.

```ruby
sitemaps.build do
sitemap "default", "My Residence" do
frame label: "Control" do
text label: "Climate", icon: "if:mdi:home-thermometer-outline" do
frame label: "Main Floor" do
text item: MainFloor_AmbTemp
switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat]
setpoint item: MainFloorThermostate_SetPoint, label: "Set Point", visibility: "MainFloorThermostat_TargetMode!=off"
end
frame label: "Basement" do
text item: Basement_AmbTemp
switch item: BasementThermostat_TargetMode, label: "Mode", mappings: { OFF: "off", COOL: "cool", HEAT: "heat" }
setpoint item: BasementThermostate_SetPoint, label: "Set Point", visibility: "BasementThermostat_TargetMode!=off"
end
end
end
end
end
```

## File Based Rules

### Basic Rule Structure
Expand Down
2 changes: 1 addition & 1 deletion lib/openhab/core/items/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def to_a
# @yield Block executed in the context of a {DSL::Items::Builder}
# @return [Object] The return value of the block.
#
# (see Items::Builder)
# @see DSL::Items::Builder
#
def build(preferred_provider = nil, &block)
DSL::Items::BaseBuilderDSL.new(preferred_provider).instance_eval_with_dummy_items(&block)
Expand Down
2 changes: 1 addition & 1 deletion lib/openhab/core/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Provider < org.openhab.core.common.registry.AbstractProvider

# Known supported provider types
# @return [Array<Symbol>]
# @!visibility private
KNOWN_TYPES = %i[items metadata things links].freeze

class << self
Expand Down Expand Up @@ -223,7 +224,6 @@ def unregister
def initialize(unload_priority: nil)
super()
@elements = java.util.concurrent.ConcurrentHashMap.new
# @deprecated OH3.4 safe navigation only required for missing Semantics registry
self.class.registry&.add_provider(self)
ScriptHandling.script_unloaded(priority: unload_priority) { unregister }
end
Expand Down
132 changes: 132 additions & 0 deletions lib/openhab/core/sitemaps/provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# frozen_string_literal: true

require "singleton"

module OpenHAB
module Core
#
# Contains sitemap related classes.
#
module Sitemaps
#
# Provides sitemaps created in Ruby to openHAB
#
class Provider < Core::Provider
PREFIX = "jruby_"
SUFFIX = ".sitemap"
private_constant :PREFIX, :SUFFIX

class << self
# @!visibility private
def registry
nil
end
end

include org.openhab.core.model.sitemap.SitemapProvider

# @!visibility private
alias_method :getSitemap, :get

# rubocop:disable Naming/MethodName

# @!visibility private
def getSitemapNames
@elements.key_set
end

# @!visibility private
def addModelChangeListener(listener)
@listeners.add(listener)
end

# @!visibility private
def removeModelChangeListener(listener)
@listeners.remove(listener)
end

# rubocop:enable Naming/MethodName

# @!visibility private
def unregister
@registration.unregister
end

# rubocop:disable Layout/LineLength

#
# Enter the Sitemap Builder DSL.
#
# @yield Block executed in the context of a {DSL::Sitemaps::Builder}
# @return [void]
#
# @see DSL::Sitemaps::Builder
#
# @example
# sitemaps.build do
# sitemap "default", "My Residence" do
# frame label: "Control" do
# text label: "Climate", icon: "if:mdi:home-thermometer-outline" do
# frame label: "Main Floor" do
# text item: MainFloor_AmbTemp
# switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat]
# setpoint item: MainFloorThermostate_SetPoint, label: "Set Point", visibility: "MainFloorThermostat_TargetMode!=off"
# end
# frame label: "Basement" do
# text item: Basement_AmbTemp
# switch item: BasementThermostat_TargetMode, label: "Mode", mappings: { OFF: "off", COOL: "cool", HEAT: "heat" }
# setpoint item: BasementThermostate_SetPoint, label: "Set Point", visibility: "BasementThermostat_TargetMode!=off"
# end
# end
# end
# end
# end
#
def build(&block)
DSL::Sitemaps::Builder.new(self).instance_eval(&block)
end
# rubocop:enable Layout/LineLength

# For use in specs
# @!visibility private
def clear
elements = @elements
@elements = java.util.concurrent.ConcurrentHashMap.new
elements.each_value do |v|
notify_listeners_about_removed_element(v)
end
end

#
# Remove a sitemap.
#
# @param [String] sitemap_name
# @return [Boolean] If a sitemap was removed
def remove(sitemap_name)
super("#{PREFIX}#{sitemap_name}#{SUFFIX}")
end

private

def initialize
super
@listeners = java.util.concurrent.CopyOnWriteArraySet.new

@registration = OSGi.register_service(self, org.openhab.core.model.sitemap.SitemapProvider)
end

def notify_listeners_about_added_element(element)
@listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::ADDED) }
end

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) }
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/openhab/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ def items
Core::Items::Registry.instance
end

# @return [Core::Sitemaps::Provider]
def sitemaps
Core::Sitemaps::Provider.instance
end

#
# Get all things known to openHAB
#
Expand Down
Loading

0 comments on commit 4c73e6f

Please sign in to comment.