Class: OpenHAB::Core::Items::GroupItem

Inherits:
GenericItem show all
Includes:
DSL::Items::TimedCommand
Defined in:
lib/openhab/core/items/group_item.rb,
lib/openhab/core/items/semantics.rb

Overview

A group behaves like a regular item, but also has #members which are nested items that can be enumerated.

If the group has a particular type, the methods from that type are directly available.

The examples all assume the following items exist.

Group House
// Location perspective
Group GroundFloor  (House)
Group Livingroom   (GroundFloor)
// Functional perspective
Group Sensors      (House)
Group Temperatures (Sensors)

Number Livingroom_Temperature "Living Room temperature" (Livingroom, Temperatures)
Number Bedroom_Temp "Bedroom temperature" (GroundFloor, Temperatures)
Number Den_Temp "Den temperature" (GroundFloor, Temperatures)

Examples:

Operate on items in a group using enumerable methods

logger.info("Total Temperatures: #{Temperatures.members.count}")
# Total Temperatures: 3
logger.info("Temperatures: #{House.members.map(&:name).sort.join(', ')}")
# Temperatures: GroundFloor, Sensors

Access to the methods and attributes like any item

logger.info("Group: #{Temperatures.name}" # Group: Temperatures'

Operates on items in nested groups using enumerable methods

logger.info("House Count: #{House.all_members.count}")
# House Count: 7
logger.info("Items: #{House.all_members.grep_v(GroupItem).map(&:label).sort.join(', ')}")
# Items: Bedroom temperature, Den temperature, Living Room temperature

Iterate through the direct members of the group

Temperatures.members.each do |item|
  logger.info("#{item.label} is: #{item.state}")
end
# Living Room temperature is 22
# Bedroom temperature is 21
# Den temperature is 19
rule 'Turn off any switch that changes' do
  changed Switches.members
  triggered(&:off)
end

Built in Enumerable functions can be applied to groups.

logger.info("Max is #{Temperatures.members.map(&:state).max}")
logger.info("Min is #{Temperatures.members.map(&:state).min}")

Defined Under Namespace

Classes: Members

Constant Summary

Constants included from Semantics

Semantics::Equipment, Semantics::Location, Semantics::Point, Semantics::Property, Semantics::Tag

Instance Attribute Summary collapse

Attributes inherited from GenericItem

#category, #formatted_state, #label, #name, #raw_state, #state, #tags

Attributes included from Semantics

#equipment, #equipment_type, #location, #location_type, #point_type, #property_type, #semantic_type

Attributes included from Item

#accepted_command_types, #accepted_data_types, #all_groups, #channel, #channel_uid, #channel_uids, #channels, #groups, #links, #metadata, #name, #provider, #thing, #things

Method Summary

Methods included from DSL::Items::TimedCommand

#command

Methods inherited from GenericItem

#command, #modify, #null?, #refresh, #state?, #time_series=, #undef?, #update

Methods included from Semantics

add, #equipment?, #location?, lookup, #point?, #points, remove, #semantic?, tags

Methods included from Item

#color_item?, #contact_item?, #date_time_item?, #dimmer_item?, #group_item?, #image_item?, #inspect, #link, #location_item?, #member_of?, #number_item?, #player_item?, #rollershutter_item?, #string_item?, #switch_item?, #tagged?, #to_s, #unlink

Methods included from Persistence

#all_states_between, #all_states_since, #average_between, #average_since, #changed_between?, #changed_since?, #count_between, #count_since, #count_state_changes_between, #count_state_changes_since, #delta_between, #delta_since, #deviation_between, #deviation_since, #evolution_rate, #historic_state, #last_update, #maximum_between, #maximum_since, #minimum_between, #minimum_since, #persist, #previous_state, #sum_between, #sum_since, #updated_between?, #updated_since?, #variance_between, #variance_since

Methods included from DSL::Items::Ensure::Ensurable

#ensure

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)

Delegate missing methods to #base_item if possible



182
183
184
185
186
# File 'lib/openhab/core/items/group_item.rb', line 182

def method_missing(method, *args, &block)
  return base_item.__send__(method, *args, &block) if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation nil responds to :to_a

  super
end

Instance Attribute Details

#all_membersArray (readonly)

Returns Get all non-group members of the group recursively.

Returns:

  • (Array)

    Get all non-group members of the group recursively.

See Also:



137
138
139
# File 'lib/openhab/core/items/group_item.rb', line 137

def all_members
  getAllMembers.map { |m| Proxy.new(m) }
end

#base_itemItem? (readonly)

Returns A typed item if the group has a particular type.

Returns:

  • (Item, nil)

    A typed item if the group has a particular type.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/openhab/core/items/group_item.rb', line 71

class GroupItem < GenericItem
  #
  # Class for indicating to triggers that a group trigger should be used
  #
  class Members
    include LazyArray

    # @return [GroupItem]
    attr_reader :group

    # @!visibility private
    def initialize(group_item)
      @group = group_item
    end

    # Explicit conversion to Array
    #
    # @return [Array]
    def to_a
      group.get_members.map { |i| Proxy.new(i) }
    end

    # Name of the group
    #
    # @return [String]
    def name
      group.name
    end

    # @return [String]
    def inspect
      r = "#<OpenHAB::Core::Items::GroupItems::Members #{name}"
      r += " #{map(&:name).inspect}>" unless @group.__getobj__.nil?
      "#{r}>"
    end
    alias_method :to_s, :inspect
  end

  # @!attribute [r] function
  # @return [GroupFunction] Returns the function of this GroupItem

  # Override because we want to send them to the base item if possible
  %i[command update].each do |method|
    define_method(method) do |command|
      return base_item.__send__(method, command) if base_item

      super(command)
    end
  end

  #
  # @!attribute [r] members
  # @return [Members] Get an Array-like object representing the members of the group
  #
  # @see Enumerable
  #
  def members
    Members.new(Proxy.new(self))
  end

  #
  # @!attribute [r] all_members
  # @return [Array] Get all non-group members of the group recursively.
  #
  # @see Enumerable
  #
  def all_members
    getAllMembers.map { |m| Proxy.new(m) }
  end

  # give the base item type a chance to format commands
  # @!visibility private
  def format_type(command)
    return super unless base_item

    base_item.format_type(command)
  end

  %w[color contact date_time dimmer image location number player rollershutter string switch].each do |type|
    type_class = type.gsub(/(^[a-z]|_[a-z])/) { |letter| letter[-1].upcase }
    class_eval <<~RUBY, __FILE__, __LINE__ + 1
      def #{type}_item?                      # def date_time_item?
        base_item&.is_a?(#{type_class}Item)  #   base_item&.is_a?(DateTimeItem)
      end                                    # end
    RUBY
  end

  #
  # Compares all attributes of the item with another item.
  #
  # @param other [Item] The item to compare with
  # @return [true,false] true if all attributes are equal, false otherwise
  #
  # @!visibility private
  def config_eql?(other)
    return false unless super

    base_item&.type == other.base_item&.type && function&.inspect == other.function&.inspect
  end

  private

  # Add base type and function details
  def type_details
    r = ""
    r += ":#{base_item.type}#{base_item.__send__(:type_details)}" if base_item
    r += ":#{function.inspect}" if function && function.to_s != "EQUALITY"
    r
  end

  # Delegate missing methods to {base_item} if possible
  def method_missing(method, *args, &block)
    return base_item.__send__(method, *args, &block) if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation nil responds to :to_a

    super
  end

  def respond_to_missing?(method, include_private = false)
    return true if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation

    super
  end
end

#equipmentsArray<Item> (readonly)

Returns:

See Also:



11
# File 'lib/openhab/core/items/semantics.rb', line 11

def equipments; end

#functionGroupFunction (readonly)

Returns the function of this GroupItem

Returns:



# File 'lib/openhab/core/items/group_item.rb', line 109

#locationsArray<Item> (readonly)

Returns:

See Also:



22
# File 'lib/openhab/core/items/semantics.rb', line 22

def locations; end

#membersMembers (readonly)

Returns Get an Array-like object representing the members of the group.

Returns:

  • (Members)

    Get an Array-like object representing the members of the group

See Also:



127
128
129
# File 'lib/openhab/core/items/group_item.rb', line 127

def members
  Members.new(Proxy.new(self))
end