From ea2e96397af0649228434c0d4961dba9c19c3727 Mon Sep 17 00:00:00 2001 From: Jimmy Tanagra Date: Wed, 24 Jul 2024 15:22:48 +1000 Subject: [PATCH] Fix access to context variables in UI rules Signed-off-by: Jimmy Tanagra --- lib/openhab/core.rb | 23 +++++++++++++++++++++++ lib/openhab/core/events/item_event.rb | 2 +- lib/openhab/dsl.rb | 13 +++++++++---- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/openhab/core.rb b/lib/openhab/core.rb index b6a71624fa..2f27baa0a2 100644 --- a/lib/openhab/core.rb +++ b/lib/openhab/core.rb @@ -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, 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) diff --git a/lib/openhab/core/events/item_event.rb b/lib/openhab/core/events/item_event.rb index cc7c45fd3b..0f9e5e02ab 100644 --- a/lib/openhab/core/events/item_event.rb +++ b/lib/openhab/core/events/item_event.rb @@ -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 diff --git a/lib/openhab/dsl.rb b/lib/openhab/dsl.rb index 80481c03e9..d757a43f1c 100644 --- a/lib/openhab/dsl.rb +++ b/lib/openhab/dsl.rb @@ -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