openhab-scripting 5.10.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openhab/core/events/channel_triggered_event.rb +30 -0
- data/lib/openhab/core/events/item_state_updated_event.rb +4 -3
- data/lib/openhab/core/items/dimmer_item.rb +2 -2
- data/lib/openhab/core/items/generic_item.rb +7 -1
- data/lib/openhab/core/items/player_item.rb +17 -0
- data/lib/openhab/core/items/rollershutter_item.rb +8 -0
- data/lib/openhab/core/items/semantics/enumerable.rb +19 -0
- data/lib/openhab/core/items/switch_item.rb +10 -2
- data/lib/openhab/core/items.rb +36 -12
- data/lib/openhab/core/profile_factory.rb +48 -7
- data/lib/openhab/core/sitemaps/provider.rb +6 -2
- data/lib/openhab/core/things/channel_uid.rb +10 -0
- data/lib/openhab/core/things/profile_callback.rb +4 -3
- data/lib/openhab/core/things/thing.rb +1 -0
- data/lib/openhab/core/types/decimal_type.rb +1 -1
- data/lib/openhab/core/types/quantity_type.rb +2 -2
- data/lib/openhab/dsl/config_description/builder.rb +157 -0
- data/lib/openhab/dsl/items/ensure.rb +5 -1
- data/lib/openhab/dsl/sitemaps/builder.rb +85 -48
- data/lib/openhab/dsl/things/builder.rb +27 -12
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +91 -10
- data/lib/openhab/rspec/shell.rb +27 -17
- data/lib/openhab/yard/code_objects/java/base.rb +3 -1
- data/lib/openhab/yard/code_objects/java/method_object.rb +15 -0
- data/lib/openhab/yard/handlers/jruby/base.rb +71 -16
- metadata +5 -16
| @@ -36,12 +36,9 @@ module OpenHAB | |
| 36 36 | 
             
                  # Base class for all widgets
         | 
| 37 37 | 
             
                  # @see org.openhab.core.model.sitemap.sitemap.Widget
         | 
| 38 38 | 
             
                  class WidgetBuilder
         | 
| 39 | 
            -
                    #  | 
| 40 | 
            -
                     | 
| 41 | 
            -
                     | 
| 42 | 
            -
                    COLOR_PATTERN = /((?<item>[A-Za-z]\w*)?\s*((?<condition>==|!=|<=|>=|<|>)\s*(?<sign>\+|-)?(?<state>\S+))?\s*=)?\s*(?<arg>\S+)/.freeze
         | 
| 43 | 
            -
                    # rubocop:enable Layout/LineLength, Lint/MixedRegexpCaptureTypes
         | 
| 44 | 
            -
                    private_constant :VISIBILITY_PATTERN, :COLOR_PATTERN
         | 
| 39 | 
            +
                    # This is copied directly out of UIComponentSitemapProvider.java
         | 
| 40 | 
            +
                    CONDITION_PATTERN = /(?<item>[A-Za-z]\w*)?\s*(?<condition>==|!=|<=|>=|<|>)?\s*(?<sign>\+|-)?(?<state>.+)/.freeze
         | 
| 41 | 
            +
                    private_constant :CONDITION_PATTERN
         | 
| 45 42 |  | 
| 46 43 | 
             
                    # @return [String, nil]
         | 
| 47 44 | 
             
                    attr_accessor :label
         | 
| @@ -52,15 +49,15 @@ module OpenHAB | |
| 52 49 | 
             
                    # @see https://www.openhab.org/docs/ui/sitemaps.html#icons
         | 
| 53 50 | 
             
                    attr_accessor :icon
         | 
| 54 51 | 
             
                    # Label color rules
         | 
| 55 | 
            -
                    # @return [ | 
| 52 | 
            +
                    # @return [Hash<String, String>]
         | 
| 56 53 | 
             
                    # @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
         | 
| 57 54 | 
             
                    attr_reader :label_colors
         | 
| 58 55 | 
             
                    # Value color rules
         | 
| 59 | 
            -
                    # @return [ | 
| 56 | 
            +
                    # @return [Hash<String, String>]
         | 
| 60 57 | 
             
                    # @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
         | 
| 61 58 | 
             
                    attr_reader :value_colors
         | 
| 62 59 | 
             
                    # Icon color rules
         | 
| 63 | 
            -
                    # @return [ | 
| 60 | 
            +
                    # @return [Hash<String, String>]
         | 
| 64 61 | 
             
                    # @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
         | 
| 65 62 | 
             
                    attr_reader :icon_colors
         | 
| 66 63 | 
             
                    # Visibility rules
         | 
| @@ -94,32 +91,32 @@ module OpenHAB | |
| 94 91 | 
             
                      @label = label
         | 
| 95 92 | 
             
                      @icon = icon
         | 
| 96 93 | 
             
                      @visibilities = []
         | 
| 97 | 
            -
                      @label_colors =  | 
| 98 | 
            -
                      @value_colors =  | 
| 99 | 
            -
                      @icon_colors =  | 
| 94 | 
            +
                      @label_colors = {}
         | 
| 95 | 
            +
                      @value_colors = {}
         | 
| 96 | 
            +
                      @icon_colors = {}
         | 
| 100 97 |  | 
| 101 | 
            -
                      self.label_color( | 
| 102 | 
            -
                      self.value_color( | 
| 103 | 
            -
                      self.icon_color( | 
| 98 | 
            +
                      self.label_color(label_color) if label_color
         | 
| 99 | 
            +
                      self.value_color(value_color) if value_color
         | 
| 100 | 
            +
                      self.icon_color(icon_color) if icon_color
         | 
| 104 101 | 
             
                      self.visibility(*visibility) if visibility
         | 
| 105 102 | 
             
                    end
         | 
| 106 103 |  | 
| 107 104 | 
             
                    # Adds one or more new rules for setting the label color
         | 
| 108 | 
            -
                    # @return [ | 
| 109 | 
            -
                    def label_color( | 
| 110 | 
            -
                      @label_colors. | 
| 105 | 
            +
                    # @return [Hash<String, String>] the current rules
         | 
| 106 | 
            +
                    def label_color(rules)
         | 
| 107 | 
            +
                      @label_colors.merge!(rules)
         | 
| 111 108 | 
             
                    end
         | 
| 112 109 |  | 
| 113 110 | 
             
                    # Adds one or more new rules for setting the value color
         | 
| 114 | 
            -
                    # @return [ | 
| 115 | 
            -
                    def value_color( | 
| 116 | 
            -
                      @value_colors. | 
| 111 | 
            +
                    # @return [Hash<String, String>] the current rules
         | 
| 112 | 
            +
                    def value_color(rules)
         | 
| 113 | 
            +
                      @value_colors.merge!(rules)
         | 
| 117 114 | 
             
                    end
         | 
| 118 115 |  | 
| 119 116 | 
             
                    # Adds one or more new rules for setting the icon color
         | 
| 120 | 
            -
                    # @return [ | 
| 121 | 
            -
                    def icon_color( | 
| 122 | 
            -
                      @icon_colors. | 
| 117 | 
            +
                    # @return [Hash<String, String>] the current rules
         | 
| 118 | 
            +
                    def icon_color(rules)
         | 
| 119 | 
            +
                      @icon_colors.merge!(rules)
         | 
| 123 120 | 
             
                    end
         | 
| 124 121 |  | 
| 125 122 | 
             
                    # Adds one or more new visibility rules
         | 
| @@ -137,21 +134,28 @@ module OpenHAB | |
| 137 134 | 
             
                      widget.label = @label
         | 
| 138 135 | 
             
                      widget.icon = @icon
         | 
| 139 136 |  | 
| 140 | 
            -
                       | 
| 141 | 
            -
                       | 
| 142 | 
            -
                       | 
| 137 | 
            +
                      add_colors(widget, :label_color, label_colors)
         | 
| 138 | 
            +
                      add_colors(widget, :value_color, value_colors)
         | 
| 139 | 
            +
                      add_colors(widget, :icon_color, icon_colors)
         | 
| 143 140 |  | 
| 144 | 
            -
                       | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 141 | 
            +
                      # @deprecated OH 4.1
         | 
| 142 | 
            +
                      if SitemapBuilder.factory.respond_to?(:create_condition)
         | 
| 143 | 
            +
                        add_conditions(widget, :visibility, visibilities, :create_visibility_rule)
         | 
| 144 | 
            +
                      else
         | 
| 145 | 
            +
                        visibilities.each do |v|
         | 
| 146 | 
            +
                          raise ArgumentError, "AND conditions not supported prior to openHAB 4.1" if v.is_a?(Array)
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                          unless (match = CONDITION_PATTERN.match(v))
         | 
| 149 | 
            +
                            raise ArgumentError, "Syntax error in visibility rule #{v.inspect}"
         | 
| 150 | 
            +
                          end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                          rule = SitemapBuilder.factory.create_visibility_rule
         | 
| 153 | 
            +
                          rule.item = match["item"]
         | 
| 154 | 
            +
                          rule.condition = match["condition"]
         | 
| 155 | 
            +
                          rule.sign = match["sign"]
         | 
| 156 | 
            +
                          rule.state = match["state"]
         | 
| 157 | 
            +
                          widget.visibility.add(rule)
         | 
| 147 158 | 
             
                        end
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                        rule = SitemapBuilder.factory.create_visibility_rule
         | 
| 150 | 
            -
                        rule.item = match["item"]
         | 
| 151 | 
            -
                        rule.condition = match["condition"]
         | 
| 152 | 
            -
                        rule.sign = match["sign"]
         | 
| 153 | 
            -
                        rule.state = match["state"]
         | 
| 154 | 
            -
                        widget.visibility.add(rule)
         | 
| 155 159 | 
             
                      end
         | 
| 156 160 |  | 
| 157 161 | 
             
                      widget
         | 
| @@ -169,19 +173,51 @@ module OpenHAB | |
| 169 173 |  | 
| 170 174 | 
             
                    private
         | 
| 171 175 |  | 
| 172 | 
            -
                    def  | 
| 173 | 
            -
                       | 
| 174 | 
            -
                         | 
| 175 | 
            -
             | 
| 176 | 
            +
                    def add_colors(widget, method, conditions)
         | 
| 177 | 
            +
                      conditions.each do |condition, color|
         | 
| 178 | 
            +
                        condition = [condition] unless condition.is_a?(Array)
         | 
| 179 | 
            +
                        add_conditions(widget, method, condition, :create_color_array) do |color_array|
         | 
| 180 | 
            +
                          color_array.arg = color
         | 
| 181 | 
            +
                        end
         | 
| 182 | 
            +
                      end
         | 
| 183 | 
            +
                    end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                    def add_conditions(widget, method, conditions, container_method)
         | 
| 186 | 
            +
                      return if conditions.empty?
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                      object = widget.send(method)
         | 
| 189 | 
            +
                      has_and_conditions = conditions.any?(Array)
         | 
| 190 | 
            +
                      # @deprecated OH 4.1
         | 
| 191 | 
            +
                      if !SitemapBuilder.factory.respond_to?(:create_condition) && has_and_conditions
         | 
| 192 | 
            +
                        raise ArgumentError, "AND conditions not supported prior to openHAB 4.1"
         | 
| 193 | 
            +
                      end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                      conditions = [conditions] unless has_and_conditions
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                      conditions.each do |sub_conditions|
         | 
| 198 | 
            +
                        container = SitemapBuilder.factory.send(container_method)
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                        add_conditions_to_container(container, sub_conditions)
         | 
| 201 | 
            +
                        yield container if block_given?
         | 
| 202 | 
            +
                        object.add(container)
         | 
| 203 | 
            +
                      end
         | 
| 204 | 
            +
                    end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                    def add_conditions_to_container(container, conditions)
         | 
| 207 | 
            +
                      # @deprecated OH 4.1
         | 
| 208 | 
            +
                      supports_and_conditions = SitemapBuilder.factory.respond_to?(:create_condition)
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                      Array.wrap(conditions).each do |c|
         | 
| 211 | 
            +
                        unless (match = CONDITION_PATTERN.match(c))
         | 
| 212 | 
            +
                          raise ArgumentError, "Syntax error in condition #{c.inspect}"
         | 
| 176 213 | 
             
                        end
         | 
| 177 214 |  | 
| 178 | 
            -
                         | 
| 179 | 
            -
                         | 
| 180 | 
            -
                         | 
| 181 | 
            -
                         | 
| 182 | 
            -
                         | 
| 183 | 
            -
                         | 
| 184 | 
            -
                        widget_color.add(color)
         | 
| 215 | 
            +
                        condition = supports_and_conditions ? SitemapBuilder.factory.create_condition : container
         | 
| 216 | 
            +
                        condition.item = match["item"]
         | 
| 217 | 
            +
                        condition.condition = match["condition"]
         | 
| 218 | 
            +
                        condition.sign = match["sign"]
         | 
| 219 | 
            +
                        condition.state = match["state"]
         | 
| 220 | 
            +
                        container.conditions.add(condition) if supports_and_conditions
         | 
| 185 221 | 
             
                      end
         | 
| 186 222 | 
             
                    end
         | 
| 187 223 | 
             
                  end
         | 
| @@ -284,6 +320,7 @@ module OpenHAB | |
| 284 320 |  | 
| 285 321 | 
             
                      @switch = switch
         | 
| 286 322 | 
             
                      @frequency = frequency
         | 
| 323 | 
            +
                      @switch_enabled = nil
         | 
| 287 324 | 
             
                    end
         | 
| 288 325 |  | 
| 289 326 | 
             
                    # (see #switch=)
         | 
| @@ -210,7 +210,18 @@ module OpenHAB | |
| 210 210 | 
             
                          thing_type,
         | 
| 211 211 | 
             
                          self.class.config_description_registry
         | 
| 212 212 | 
             
                        )
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                        predefined_channels = self.class.thing_factory_helper
         | 
| 215 | 
            +
                                                  .create_channels(thing_type, uid, self.class.config_description_registry)
         | 
| 216 | 
            +
                                                  .to_h { |channel| [channel.uid, channel] }
         | 
| 217 | 
            +
                        new_channels = channels.to_h { |channel| [channel.uid, channel] }
         | 
| 218 | 
            +
                        merged_channels = predefined_channels.merge(new_channels) do |_key, predefined_channel, new_channel|
         | 
| 219 | 
            +
                          predefined_channel.configuration.merge!(new_channel.configuration)
         | 
| 220 | 
            +
                          predefined_channel
         | 
| 221 | 
            +
                        end
         | 
| 222 | 
            +
                        @channels = merged_channels.values
         | 
| 213 223 | 
             
                      end
         | 
| 224 | 
            +
             | 
| 214 225 | 
             
                      builder = org.openhab.core.thing.binding.builder.ThingBuilder
         | 
| 215 226 | 
             
                                   .create(thing_type_uid, uid)
         | 
| 216 227 | 
             
                                   .with_label(label)
         | 
| @@ -219,15 +230,7 @@ module OpenHAB | |
| 219 230 | 
             
                                   .with_bridge(bridge_uid)
         | 
| 220 231 | 
             
                                   .with_channels(channels)
         | 
| 221 232 |  | 
| 222 | 
            -
                      if thing_type
         | 
| 223 | 
            -
                        # can't use with_channels, or it will wipe out custom channels from above
         | 
| 224 | 
            -
                        self.class.thing_factory_helper.create_channels(thing_type,
         | 
| 225 | 
            -
                                                                        uid,
         | 
| 226 | 
            -
                                                                        self.class.config_description_registry).each do |channel|
         | 
| 227 | 
            -
                          builder.with_channel(channel)
         | 
| 228 | 
            -
                        end
         | 
| 229 | 
            -
                        builder.with_properties(thing_type.properties)
         | 
| 230 | 
            -
                      end
         | 
| 233 | 
            +
                      builder.with_properties(thing_type.properties) if thing_type
         | 
| 231 234 |  | 
| 232 235 | 
             
                      builder.build
         | 
| 233 236 | 
             
                    end
         | 
| @@ -263,8 +266,14 @@ module OpenHAB | |
| 263 266 | 
             
                                :default_tags,
         | 
| 264 267 | 
             
                                :properties,
         | 
| 265 268 | 
             
                                :description,
         | 
| 266 | 
            -
                                :auto_update_policy | 
| 267 | 
            -
             | 
| 269 | 
            +
                                :auto_update_policy
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                    class << self
         | 
| 272 | 
            +
                      # @!visibility private
         | 
| 273 | 
            +
                      def channel_type_registry
         | 
| 274 | 
            +
                        @channel_type_registry ||= OSGi.service("org.openhab.core.thing.type.ChannelTypeRegistry")
         | 
| 275 | 
            +
                      end
         | 
| 276 | 
            +
                    end
         | 
| 268 277 |  | 
| 269 278 | 
             
                    #
         | 
| 270 279 | 
             
                    # Constructor for ChannelBuilder
         | 
| @@ -284,7 +293,7 @@ module OpenHAB | |
| 284 293 | 
             
                    #   The default tags for this channel.
         | 
| 285 294 | 
             
                    # @param [:default, :recommend, :veto, org.openhab.core.thing.type.AutoUpdatePolicy] auto_update_policy
         | 
| 286 295 | 
             
                    #   The channel's auto update policy.
         | 
| 287 | 
            -
                    # @param [String] accepted_item_type The accepted item type.
         | 
| 296 | 
            +
                    # @param [String] accepted_item_type The accepted item type. If nil, infer the item type from the channel type.
         | 
| 288 297 | 
             
                    #
         | 
| 289 298 | 
             
                    def initialize(uid,
         | 
| 290 299 | 
             
                                   type,
         | 
| @@ -343,6 +352,12 @@ module OpenHAB | |
| 343 352 | 
             
                         .build
         | 
| 344 353 | 
             
                    end
         | 
| 345 354 |  | 
| 355 | 
            +
                    # @!attribute [r] accepted_item_type
         | 
| 356 | 
            +
                    # @return [String] The accepted item type.
         | 
| 357 | 
            +
                    def accepted_item_type
         | 
| 358 | 
            +
                      @accepted_item_type ||= self.class.channel_type_registry.get_channel_type(type)&.item_type
         | 
| 359 | 
            +
                    end
         | 
| 360 | 
            +
             | 
| 346 361 | 
             
                    private
         | 
| 347 362 |  | 
| 348 363 | 
             
                    def kind
         | 
    
        data/lib/openhab/dsl/version.rb
    CHANGED
    
    
    
        data/lib/openhab/dsl.rb
    CHANGED
    
    | @@ -77,7 +77,13 @@ module OpenHAB | |
| 77 77 | 
             
                #
         | 
| 78 78 | 
             
                # Defines a new profile that can be applied to item channel links.
         | 
| 79 79 | 
             
                #
         | 
| 80 | 
            +
                # To create a profile that can be used in the UI, provide a label and optionally a {config_description},
         | 
| 81 | 
            +
                # otherwise the profile will not be visible in the UI.
         | 
| 82 | 
            +
                #
         | 
| 80 83 | 
             
                # @param [String, Symbol] id The id for the profile.
         | 
| 84 | 
            +
                # @param [String, nil] label The label for the profile. When nil, the profile will not be visible in the UI.
         | 
| 85 | 
            +
                # @param [org.openhab.core.config.core.ConfigDescription, nil] config_description
         | 
| 86 | 
            +
                #   The configuration description for the profile so that it can be configured in the UI.
         | 
| 81 87 | 
             
                # @yield [event, command: nil, state: nil, callback:, link:, item:, channel_uid:, configuration:, context:]
         | 
| 82 88 | 
             
                #   All keyword params are optional. Any that aren't defined won't be passed.
         | 
| 83 89 | 
             
                # @yieldparam [:command_from_item, :state_from_item, :command_from_handler, :state_from_handler] event
         | 
| @@ -97,8 +103,8 @@ module OpenHAB | |
| 97 103 | 
             
                # @yieldreturn [Boolean] Return true from the block in order to have default processing.
         | 
| 98 104 | 
             
                # @return [void]
         | 
| 99 105 | 
             
                #
         | 
| 100 | 
            -
                # @see org.openhab.thing.Profile
         | 
| 101 | 
            -
                # @see org.openhab.thing.StateProfile
         | 
| 106 | 
            +
                # @see org.openhab.core.thing.profiles.Profile
         | 
| 107 | 
            +
                # @see org.openhab.core.thing.profiles.StateProfile
         | 
| 102 108 | 
             
                #
         | 
| 103 109 | 
             
                # @example Vetoing a command
         | 
| 104 110 | 
             
                #   profile(:veto_closing_shades) do |event, item:, command:|
         | 
| @@ -142,17 +148,54 @@ module OpenHAB | |
| 142 148 | 
             
                #   # can also be referenced from an `.items` file:
         | 
| 143 149 | 
             
                #   # Number:Temperature MyTempWithNonUnitValueFromBinding "I prefer Celsius [%d °C]" { channel="something_that_returns_F"[profile="ruby:set_uom", unit="°F"] }
         | 
| 144 150 | 
             
                #
         | 
| 145 | 
            -
                 | 
| 151 | 
            +
                # @example Create a profile that is usable in the UI
         | 
| 152 | 
            +
                #   config_description = config_description do
         | 
| 153 | 
            +
                #     parameter :min, :decimal, label: "Minimum", description: "Minimum value"
         | 
| 154 | 
            +
                #     parameter :max, :decimal, label: "Maximum", description: "Maximum value"
         | 
| 155 | 
            +
                #   end
         | 
| 156 | 
            +
                #
         | 
| 157 | 
            +
                #   profile(:range_filter, label: "Range Filter", config_description: config_description) do |event, state:, configuration:|
         | 
| 158 | 
            +
                #     return true unless event == :state_from_handler
         | 
| 159 | 
            +
                #
         | 
| 160 | 
            +
                #     (configuration["min"]..configuration["max"]).cover?(state)
         | 
| 161 | 
            +
                #   end
         | 
| 162 | 
            +
                #
         | 
| 163 | 
            +
                def profile(id, label: nil, config_description: nil, &block)
         | 
| 146 164 | 
             
                  raise ArgumentError, "Block is required" unless block
         | 
| 147 165 |  | 
| 148 166 | 
             
                  id = id.to_s
         | 
| 149 | 
            -
                  uid = org.openhab.core.thing.profiles.ProfileTypeUID.new("ruby", id)
         | 
| 150 167 |  | 
| 151 168 | 
             
                  ThreadLocal.thread_local(openhab_rule_type: "profile", openhab_rule_uid: id) do
         | 
| 152 | 
            -
                    Core::ProfileFactory.instance.register( | 
| 169 | 
            +
                    Core::ProfileFactory.instance.register(id, block, label: label, config_description: config_description)
         | 
| 153 170 | 
             
                  end
         | 
| 154 171 | 
             
                end
         | 
| 155 172 |  | 
| 173 | 
            +
                #
         | 
| 174 | 
            +
                # Create a {org.openhab.core.config.core.ConfigDescription ConfigDescription} object.
         | 
| 175 | 
            +
                #
         | 
| 176 | 
            +
                # @param [String, java.net.URI] uri The URI for the ConfigDescription. When nil, a dummy URI is used which will
         | 
| 177 | 
            +
                #   be replaced by the profile with the correct URI for that profile.
         | 
| 178 | 
            +
                # @yield Block that consists of {ConfigDescription::Builder#parameter} and {ConfigDescription::Builder#group} calls.
         | 
| 179 | 
            +
                #
         | 
| 180 | 
            +
                # @return [org.openhab.core.config.core.ConfigDescription]
         | 
| 181 | 
            +
                #   The created {org.openhab.core.config.core.ConfigDescription ConfigDescription} object
         | 
| 182 | 
            +
                #
         | 
| 183 | 
            +
                # @example
         | 
| 184 | 
            +
                #  config_description = config_description do
         | 
| 185 | 
            +
                #    parameter :ungrouped_parameter, :decimal, label: "Ungrouped Parameter", min: 1, max: 5
         | 
| 186 | 
            +
                #
         | 
| 187 | 
            +
                #    group "Config Group", label: "Grouped parameters", advanced: true do
         | 
| 188 | 
            +
                #      parameter :my_parameter, :string, label: "My Parameter", description: "My Parameter Description"
         | 
| 189 | 
            +
                #      parameter :other_parameter, :integer, label: "Other Parameter", description: "Other Parameter Description"
         | 
| 190 | 
            +
                #    end
         | 
| 191 | 
            +
                #  end
         | 
| 192 | 
            +
                #
         | 
| 193 | 
            +
                def config_description(uri = nil, &block)
         | 
| 194 | 
            +
                  raise ArgumentError, "Block is required" unless block
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                  ConfigDescription::Builder.new.build(uri, &block)
         | 
| 197 | 
            +
                end
         | 
| 198 | 
            +
             | 
| 156 199 | 
             
                # rubocop:enable Layout/LineLength
         | 
| 157 200 |  | 
| 158 201 | 
             
                # @!group Object Access
         | 
| @@ -557,10 +600,49 @@ module OpenHAB | |
| 557 600 | 
             
                #   to reduce repetitions
         | 
| 558 601 | 
             
                #
         | 
| 559 602 |  | 
| 603 | 
            +
                #
         | 
| 604 | 
            +
                # Permanently enable conditional execution of commands and updates for the current thread.
         | 
| 605 | 
            +
                #
         | 
| 606 | 
            +
                # When conditional executions are enabled, commands and updates will only be sent if the
         | 
| 607 | 
            +
                # item's current state is not the same as the command or updated state.
         | 
| 608 | 
            +
                # This eliminates the need to chain the command and update calls through
         | 
| 609 | 
            +
                # {DSL::Items::Ensure::Ensurable#ensure ensure}.
         | 
| 610 | 
            +
                #
         | 
| 611 | 
            +
                # When conditional executions are enabled either by this method or within a block of {ensure_states},
         | 
| 612 | 
            +
                # commands and updates can still be forcefully executed using the corresponding bang methods, e.g.
         | 
| 613 | 
            +
                # `Item1.on!`, `Item1.command!(50)`, or `Item1.update!(ON)`.
         | 
| 614 | 
            +
                #
         | 
| 615 | 
            +
                # @note This method is only intended for use at the top level of rule
         | 
| 616 | 
            +
                #   scripts. If it's used within library methods, or hap-hazardly within
         | 
| 617 | 
            +
                #   rules, things can get very confusing because the prior state won't be
         | 
| 618 | 
            +
                #   properly restored.
         | 
| 619 | 
            +
                #
         | 
| 620 | 
            +
                # @param [Boolean] active Whether to enable or disable conditional executions.
         | 
| 621 | 
            +
                # @return [Boolean] The previous ensure_states setting.
         | 
| 622 | 
            +
                #
         | 
| 623 | 
            +
                # @example Make ensure_states the default for the rest of the script
         | 
| 624 | 
            +
                #   ensure_states!
         | 
| 625 | 
            +
                #
         | 
| 626 | 
            +
                #   # From now, all commands are "ensured", i.e. only sent when the current state is different
         | 
| 627 | 
            +
                #   Item1.on
         | 
| 628 | 
            +
                #   Item2.command(ON)
         | 
| 629 | 
            +
                #
         | 
| 630 | 
            +
                #   # While ensure_states! is active, we can still forcibly send a command
         | 
| 631 | 
            +
                #   # regardless of the item's current state
         | 
| 632 | 
            +
                #   Item2.on!
         | 
| 633 | 
            +
                #
         | 
| 634 | 
            +
                # @see ensure_states
         | 
| 635 | 
            +
                #
         | 
| 636 | 
            +
                def ensure_states!(active: true)
         | 
| 637 | 
            +
                  old = Thread.current[:openhab_ensure_states]
         | 
| 638 | 
            +
                  Thread.current[:openhab_ensure_states] = active
         | 
| 639 | 
            +
                  old
         | 
| 640 | 
            +
                end
         | 
| 641 | 
            +
             | 
| 560 642 | 
             
                #
         | 
| 561 643 | 
             
                # Global method that takes a block and for the duration of the block
         | 
| 562 644 | 
             
                # all commands sent will check if the item is in the command's state
         | 
| 563 | 
            -
                # before sending the command.
         | 
| 645 | 
            +
                # before sending the command. This also applies to updates.
         | 
| 564 646 | 
             
                #
         | 
| 565 647 | 
             
                # @yield
         | 
| 566 648 | 
             
                # @return [Object] The result of the block.
         | 
| @@ -603,11 +685,10 @@ module OpenHAB | |
| 603 685 | 
             
                #   end
         | 
| 604 686 | 
             
                #
         | 
| 605 687 | 
             
                def ensure_states
         | 
| 606 | 
            -
                  old =  | 
| 607 | 
            -
                  Thread.current[:openhab_ensure_states] = true
         | 
| 688 | 
            +
                  old = ensure_states!
         | 
| 608 689 | 
             
                  yield
         | 
| 609 690 | 
             
                ensure
         | 
| 610 | 
            -
                   | 
| 691 | 
            +
                  ensure_states!(active: old)
         | 
| 611 692 | 
             
                end
         | 
| 612 693 |  | 
| 613 694 | 
             
                #
         | 
| @@ -841,7 +922,7 @@ module OpenHAB | |
| 841 922 | 
             
                #     elements, the {Core::Items::Metadata::Hash} will be passed as an argument. Therefore it's
         | 
| 842 923 | 
             
                #     recommended that you use a Proc, not a Lambda, for permissive argument matching.
         | 
| 843 924 | 
             
                #
         | 
| 844 | 
            -
                # @return [ | 
| 925 | 
            +
                # @return [Hash] the prior provider configuration.
         | 
| 845 926 | 
             
                #
         | 
| 846 927 | 
             
                # @see provider
         | 
| 847 928 | 
             
                # @see OpenHAB::Core::Provider.current Provider.current for how the current provider is calculated
         | 
    
        data/lib/openhab/rspec/shell.rb
    CHANGED
    
    | @@ -5,26 +5,36 @@ module OpenHAB | |
| 5 5 | 
             
                # based on https://stackoverflow.com/questions/1197224/source-shell-script-into-environment-within-a-ruby-script#19826329
         | 
| 6 6 | 
             
                # @!visibility private
         | 
| 7 7 | 
             
                module Shell
         | 
| 8 | 
            -
                   | 
| 8 | 
            +
                  # @!visibility private
         | 
| 9 | 
            +
                  DEFAULT_PRINTENV_COMMAND = "printenv -0"
         | 
| 10 | 
            +
                  @printenv_command = DEFAULT_PRINTENV_COMMAND
         | 
| 11 | 
            +
                  @printenv_separator = "\0"
         | 
| 9 12 |  | 
| 10 | 
            -
                   | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
                    cmd =  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 13 | 
            +
                  class << self
         | 
| 14 | 
            +
                    # Read in the bash environment, after an optional command.
         | 
| 15 | 
            +
                    #   Returns Array of key/value pairs.
         | 
| 16 | 
            +
                    def shell_env(cmd = nil)
         | 
| 17 | 
            +
                      cmd = "#{cmd} > #{IO::NULL}; " if cmd
         | 
| 18 | 
            +
                      env = `#{cmd}#{@printenv_command} 2> #{IO::NULL}`
         | 
| 19 | 
            +
                      if !$?.success? && @printenv_command.equal?(DEFAULT_PRINTENV_COMMAND)
         | 
| 20 | 
            +
                        @printenv_command = "printenv"
         | 
| 21 | 
            +
                        @printenv_separator = "\n"
         | 
| 22 | 
            +
                        env = `#{cmd}#{@printenv_command}`
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                      env.split(@printenv_separator).map { |l| l.split("=", 2) }
         | 
| 25 | 
            +
                    end
         | 
| 17 26 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 27 | 
            +
                    # Source a given file, and compare environment before and after.
         | 
| 28 | 
            +
                    #   Returns Hash of any keys that have changed.
         | 
| 29 | 
            +
                    def shell_source(file)
         | 
| 30 | 
            +
                      (shell_env(". #{File.realpath(file)}") - shell_env).to_h
         | 
| 31 | 
            +
                    end
         | 
| 23 32 |  | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 33 | 
            +
                    # Find variables changed as a result of sourcing the given file,
         | 
| 34 | 
            +
                    #   and update in ENV.
         | 
| 35 | 
            +
                    def source_env_from(file)
         | 
| 36 | 
            +
                      shell_source(file).each { |k, v| ENV[k] = v }
         | 
| 37 | 
            +
                    end
         | 
| 28 38 | 
             
                  end
         | 
| 29 39 | 
             
                end
         | 
| 30 40 | 
             
              end
         | 
| @@ -9,7 +9,9 @@ module YARD | |
| 9 9 | 
             
                  # Which might be a class, an enum, or an interface
         | 
| 10 10 | 
             
                  module Base
         | 
| 11 11 | 
             
                    module ClassMethods
         | 
| 12 | 
            -
                      def new(name)
         | 
| 12 | 
            +
                      def new(name, _suffix = nil)
         | 
| 13 | 
            +
                        # _suffix is given when it encounters a class with ::, e.g. org.openhab.core.OpenHAB::DEFAULT_CONFIG_FOLDER
         | 
| 14 | 
            +
             | 
| 13 15 | 
             
                        super(:root, name)
         | 
| 14 16 | 
             
                      end
         | 
| 15 17 | 
             
                    end
         | 
| @@ -5,27 +5,76 @@ module YARD | |
| 5 5 | 
             
                module JRuby
         | 
| 6 6 | 
             
                  module Base
         | 
| 7 7 | 
             
                    class << self
         | 
| 8 | 
            +
                      #
         | 
| 9 | 
            +
                      # Creates an external link to java documentation for a java class.
         | 
| 10 | 
            +
                      #
         | 
| 11 | 
            +
                      # The supported classes are defined in the `javadocs` configuration option.
         | 
| 12 | 
            +
                      #
         | 
| 13 | 
            +
                      # Supported syntaxes:
         | 
| 14 | 
            +
                      #   Package:
         | 
| 15 | 
            +
                      #   - org.openhab.core => href_base/org/openhab/core/package-summary.html
         | 
| 16 | 
            +
                      #
         | 
| 17 | 
            +
                      #   Class:
         | 
| 18 | 
            +
                      #   - org.openhab.core.OpenHAB => href_base/org/openhab/core/OpenHAB.html
         | 
| 19 | 
            +
                      #   This doesn't get mistaken as a constant:
         | 
| 20 | 
            +
                      #   - java.net.URI => href_base/java/net/URI.html
         | 
| 21 | 
            +
                      #
         | 
| 22 | 
            +
                      #   Constant: (To specify a constant, use Ruby's `::` syntax)
         | 
| 23 | 
            +
                      #   - org.openhab.core.OpenHAB::DEFAULT_CONFIG_FOLDER =>
         | 
| 24 | 
            +
                      #       href_base/org/openhab/core/OpenHAB.html#DEFAULT_CONFIG_FOLDER
         | 
| 25 | 
            +
                      #
         | 
| 26 | 
            +
                      #   Method:
         | 
| 27 | 
            +
                      #   - org.openhab.core.OpenHAB#getVersion() => href_base/org/openhab/core/OpenHAB.html#getVersion()
         | 
| 28 | 
            +
                      #   But can also work with constants, albeit not a valid Ruby syntax:
         | 
| 29 | 
            +
                      #   - org.openhab.core.OpenHAB#version => href_base/org/openhab/core/OpenHAB.html#version
         | 
| 30 | 
            +
                      #   - org.openhab.core.OpenHAB#DEFAULT_CONFIG_FOLDER =>
         | 
| 31 | 
            +
                      #       href_base/org/openhab/core/OpenHAB.html#DEFAULT_CONFIG_FOLDER
         | 
| 32 | 
            +
                      #
         | 
| 33 | 
            +
                      #   Inner class:
         | 
| 34 | 
            +
                      #   - org.openhab.core.config.core.ConfigDescriptionParameter::Type =>
         | 
| 35 | 
            +
                      #       href_base/org/openhab/core/config/core/ConfigDescriptionParameter.Type.html
         | 
| 36 | 
            +
                      #   - org.openhab.core.config.core.ConfigDescriptionParameter.Type =>
         | 
| 37 | 
            +
                      #       href_base/org/openhab/core/config/core/ConfigDescriptionParameter.Type.html
         | 
| 38 | 
            +
                      #
         | 
| 39 | 
            +
                      #   Constant in inner class:
         | 
| 40 | 
            +
                      #   - org.openhab.core.config.core.ConfigDescriptionParameter::Type::TEXT =>
         | 
| 41 | 
            +
                      #       href_base/org/openhab/core/config/core/ConfigDescriptionParameter.Type.html#TEXT
         | 
| 42 | 
            +
                      #   - org.openhab.core.config.core.ConfigDescriptionParameter.Type::TEXT =>
         | 
| 43 | 
            +
                      #       href_base/org/openhab/core/config/core/ConfigDescriptionParameter.Type.html#TEXT
         | 
| 44 | 
            +
                      #
         | 
| 8 45 | 
             
                      def infer_java_class(klass, inferred_type = nil, comments = nil, statement = nil)
         | 
| 9 | 
            -
                        components = klass.split(".")
         | 
| 10 | 
            -
                        components.pop if components.last == "freeze"
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                        class_first_char = components.last[0]
         | 
| 13 | 
            -
                        is_field = components.last == components.last.upcase
         | 
| 14 | 
            -
                        container_first_char = components[-2]&.[](0)
         | 
| 15 | 
            -
                        is_method = container_first_char &&
         | 
| 16 | 
            -
                                    class_first_char != class_first_char.upcase &&
         | 
| 17 | 
            -
                                    container_first_char == container_first_char.upcase
         | 
| 18 | 
            -
                        is_package = !is_method && !is_field && class_first_char != class_first_char.upcase
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                        # methods aren't supported right now
         | 
| 21 | 
            -
                        return if is_method
         | 
| 22 | 
            -
             | 
| 23 46 | 
             
                        javadocs = YARD::Config.options.dig(:jruby, "javadocs") || {}
         | 
| 24 47 |  | 
| 25 48 | 
             
                        href_base = javadocs.find { |package, _href| klass == package || klass.start_with?("#{package}.") }&.last
         | 
| 26 49 | 
             
                        return unless href_base
         | 
| 27 50 |  | 
| 51 | 
            +
                        components = klass.split(/\.(?=[A-Z])/, 2)
         | 
| 52 | 
            +
                        components.unshift(*components.shift.split("."))
         | 
| 53 | 
            +
                        components.push(components.pop.delete_suffix(".freeze"))
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                        class_first_char = components.last[0]
         | 
| 56 | 
            +
                        if /#|::/.match?(components.last)
         | 
| 57 | 
            +
                          parts = components.pop.rpartition(/#|::/)
         | 
| 58 | 
            +
                          is_field = parts.last == parts.last.upcase
         | 
| 59 | 
            +
                          # explicit method is fine, e.g. `org.openhab.core.OpenHAB#getVersion()`
         | 
| 60 | 
            +
                          is_method = !is_field
         | 
| 61 | 
            +
                          components.push(parts.first.gsub("::", "."), parts.last)
         | 
| 62 | 
            +
                        else
         | 
| 63 | 
            +
                          is_field = is_method = false
         | 
| 64 | 
            +
                          if components.last.include?(".")
         | 
| 65 | 
            +
                            parts = components.last.split(".")
         | 
| 66 | 
            +
                            if (is_method = parts.last[0] == parts.last[0].downcase)
         | 
| 67 | 
            +
                              # implicit method is not supported, e.g. `org.openhab.core.OpenHAB.version`
         | 
| 68 | 
            +
                              # because we're not sure whether it should be #version() or #getVersion()
         | 
| 69 | 
            +
                              return
         | 
| 70 | 
            +
                            end
         | 
| 71 | 
            +
                          end
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                        is_package = !is_method && !is_field && class_first_char != class_first_char.upcase
         | 
| 75 | 
            +
             | 
| 28 76 | 
             
                        inferred_type = CodeObjects::Java::FieldObject if is_field
         | 
| 77 | 
            +
                        inferred_type = CodeObjects::Java::MethodObject if is_method
         | 
| 29 78 | 
             
                        inferred_type = CodeObjects::Java::PackageObject if is_package
         | 
| 30 79 | 
             
                        if inferred_type.nil?
         | 
| 31 80 | 
             
                          docstring = Docstring.parser.parse(comments || statement&.comments).to_docstring
         | 
| @@ -36,12 +85,18 @@ module YARD | |
| 36 85 | 
             
                                          end
         | 
| 37 86 | 
             
                        end
         | 
| 38 87 |  | 
| 88 | 
            +
                        orig_klass = klass.dup
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                        # purposely calling gsub! to modify the caller's string
         | 
| 91 | 
            +
                        # YARD doesn't handle java inner classes well, so we convert them to ruby
         | 
| 92 | 
            +
                        klass.gsub!("::", ".")
         | 
| 93 | 
            +
             | 
| 39 94 | 
             
                        inferred_type.new(klass) do |o|
         | 
| 40 95 | 
             
                          o.source = statement if statement
         | 
| 41 96 | 
             
                          suffix = "/package-summary" if is_package
         | 
| 42 | 
            -
                          field = "##{components.pop}" if is_field
         | 
| 97 | 
            +
                          field = "##{components.pop}" if is_field || is_method
         | 
| 43 98 | 
             
                          link = "#{href_base}#{components.join("/")}#{suffix}.html#{field}"
         | 
| 44 | 
            -
                          o.docstring.add_tag(Tags::Tag.new(:see,  | 
| 99 | 
            +
                          o.docstring.add_tag(Tags::Tag.new(:see, orig_klass, nil, link)) unless o.docstring.has_tag?(:see)
         | 
| 45 100 | 
             
                        end
         | 
| 46 101 | 
             
                      end
         | 
| 47 102 | 
             
                    end
         |