Skip to content

Commit

Permalink
Fix access to context variables in UI rules
Browse files Browse the repository at this point in the history
Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng committed Jul 24, 2024
1 parent 6697722 commit ea2e963
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
23 changes: 23 additions & 0 deletions lib/openhab/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ def import_scope_values(scope_values)
eval("#{key} = value unless defined?(#{key})", nil, __FILE__, __LINE__) # rubocop:disable Security/Eval
end
end

#
# Returns a hash of global context variable `$ctx` injected into UI based scripts.
#
# The keys in $ctx are prefixed with the trigger module id.
# This method strips them off and symbolizes them so they are accessible without the module id prefix.
#
# @!visibility private
# @return [Hash<Symbol, Object>, nil]
#
def ui_context
# $ctx is a java.util.HashMap and its #to_h doesn't take a block like Ruby's
@ui_context ||= $ctx&.to_hash&.to_h do |key, value|
[
key.split(".", 2).last.to_sym,
case value
when Items::Item then Items::Proxy.new(value)
when Things::Thing then Things::Proxy.new(value)
else value
end
]
end.freeze
end
end

import_default_presets unless defined?($ir)
Expand Down
2 changes: 1 addition & 1 deletion lib/openhab/core/events/item_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def item
# @since openHAB 4.1 for UI rules
#
def group
triggering_group = inputs&.[]("triggeringGroup") || $ctx&.[]("triggeringGroup")
triggering_group = inputs&.[]("triggeringGroup") || Core.ui_context&.[](:triggeringGroup)
Items::Proxy.new(triggering_group) if triggering_group
end
end
Expand Down
13 changes: 9 additions & 4 deletions lib/openhab/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1094,15 +1094,20 @@ def try_parse_time_like(string)
# @!visibility private
ruby2_keywords def method_missing(method, *args)
return super unless args.empty? && !block_given?
return super unless (context = Thread.current[:openhab_context]) && context.key?(method)

logger.trace("DSL#method_missing found context variable: '#{method}'")
context[method]
if (context = Thread.current[:openhab_context]) && context.key?(method)
logger.trace("DSL#method_missing found context variable: '#{method}'")
return context[method]
elsif Core.ui_context&.key?(method)
logger.trace("DSL#method_missing found UI context variable: '#{method}'")
return Core.ui_context[method]
end
super
end

# @!visibility private
def respond_to_missing?(method, include_private = false)
Thread.current[:openhab_context]&.key?(method) || super
Thread.current[:openhab_context]&.key?(method) || Core.ui_context&.key?(method) || super
end
end
end
Expand Down

0 comments on commit ea2e963

Please sign in to comment.