class Sonos::System

The Sonos system. The root object to manage the collection of groups and devices. This is intended to be a singleton accessed from ‘Sonos.system`.

Attributes

devices[R]
groups[R]
topology[R]

Public Class Methods

new(topology = Discovery.new.topology) click to toggle source

Initialize the system @param [Array] the system topology. If this is nil, it will autodiscover.

# File lib/sonos/system.rb, line 11
def initialize(topology = Discovery.new.topology)
  rescan topology
end

Public Instance Methods

find_party_master() click to toggle source
# File lib/sonos/system.rb, line 48
def find_party_master
  # 1: If there are any pre-existing groups playing something, use
  # the lowest-numbered group's master. But ensure to only check a
  # master_speaker that is actually a speaker, and not an Accessory.
  groups.each do |group|
    if group.master_speaker.speaker? and group.master_speaker.has_music?
      return group.master_speaker
    end
  end

  # 2: Lowest-number speaker that's playing something
  speakers.each do |speaker|
    return speaker if speaker.has_music?
  end

  # 3: lowest-numbered speaker
  speakers[0]
end
party_mode(new_master = nil) click to toggle source

Party Mode! Join all speakers into a single group.

# File lib/sonos/system.rb, line 35
def party_mode new_master = nil
  return nil unless speakers.length > 1

  new_master = find_party_master if new_master.nil?

  party_over
  speakers.each do |slave|
    next if slave.uid == new_master.uid
    slave.join new_master
  end
  rescan @topology
end
party_over() click to toggle source

Party’s over :(

# File lib/sonos/system.rb, line 68
def party_over
  groups.each { |g| g.disband }
  rescan @topology
end
pause_all() click to toggle source

Pause all speakers

# File lib/sonos/system.rb, line 21
def pause_all
  speakers.each do |speaker|
    speaker.pause if speaker.has_music?
  end
end
play_all() click to toggle source

Play all speakers

# File lib/sonos/system.rb, line 28
def play_all
  speakers.each do |speaker|
    speaker.play if speaker.has_music?
  end
end
rescan(topology = Discovery.new.topology) click to toggle source
# File lib/sonos/system.rb, line 73
def rescan(topology = Discovery.new.topology)
  @topology = topology
  @groups = []
  @devices = @topology.collect(&:device)

  construct_groups

  speakers.each do |speaker|
    speaker.group_master = speaker
    @groups.each do |group|
      if group.master_speaker.uid == speaker.uid
        speaker.group_master = speaker
        group.master_speaker = speaker
      end
      group.slave_speakers.each do |slave|
        speaker.group_master = group.master_speaker if slave.uid == speaker.uid
      end
    end
  end
end
speakers() click to toggle source

Returns all speakers

# File lib/sonos/system.rb, line 16
def speakers
  @devices.select(&:speaker?)
end

Private Instance Methods

construct_groups() click to toggle source
# File lib/sonos/system.rb, line 96
def construct_groups
  # Loop through all of the unique groups
  @topology.collect(&:group).uniq.each do |group_uid|

    # set group's master nade using topology's coordinator parameter
    master = nil
    @topology.each do |node|
      # Select only the nodes with this group uid
      next unless node.group == group_uid
      master = node if node.coordinator == "true"
    end

    # Skip this group if there is no master
    next if master.nil?

    # register other nodes in groups as slave nodes
    nodes = []
    @topology.each do |node|
      # Select only the nodes with this group uid
      next unless node.group == group_uid
      nodes << node unless node.uuid == master.uuid
    end

    # Add the group
    @groups << Group.new(master.device, nodes.collect(&:device))
  end
end