Skip to main content Link Search Menu Expand Document (external link)

Groups

A group can be accessed directly by name, to access all groups use the groups method. A Group behaves like a regular Item, but also lets you iterate through it’s members and use all the available methods of Enumerable. If the group have a type all methods of that type is directly available.

Group Methods

MethodDescription
membersUsed to inform a rule that you want it to operate on the items in the group (see example below)
all_membersGets all descendants of the group recursively excluding groups. Pass :all as argument to include groups as well, or :groups to only get the sub groups. It’s also possible to pass a block to make more advanced filters
eachIterates through the members of the group and execute the code in the provided block for each member
enumerable methodsAll methods here

Use in triggers

Groups can be used in triggers in two different ways:

changed Switches # Executes the rule when the state of the group item changes

or

changed Switches.members # Executes the rule when any of the groups members changes its state

Examples

Given the following

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)

The following are log lines and the output after the comment

#Operate on items in a group using enumerable methods
logger.info("Total Temperatures: #{Temperatures.count}")     #Total Temperatures: 3'
logger.info("Temperatures: #{House.all_members.sort_by(&:label).map(&:label).join(', ')}") #Temperatures: Bedroom temperature, Den temperature, Living Room temperature' 

#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: 3
logger.info("Items: #{House.all_members.sort_by(&:label).map(&:label).join(', ')}")  # Items: Bedroom temperature, Den temperature, Living Room temperature

#Access to sub groups using all_members(:groups)
logger.info("House Sub Groups: #{House.all_members(:groups).count}")  # House Sub Groups: 4
logger.info("Groups: #{House.all_members(:groups).sort_by(&:id).map(&:id).join(', ')}")  # Groups: GroundFloor, Livingroom, Sensors, Temperatures

#Filter the items returned by `all_members` in other ways using a block
logger.info(House.all_members { |item| /.*room.*/.match?(item.name) }.sort_by(&:name).map(&:name).join(', ')) # Bedroom_Temp, Livingroom, Livingroom_Temperature

#Iterate through the direct members of the group
Temperatures.each do |item|
  logger.info("#{item.id} is: #{item}")
end
#Logs:
#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/set functions can be applied to groups.

logger.info("Max is #{Temperatures.max}")
logger.info("Min is #{Temperatures.min}")