public function getSpeakers()
{
if (is_array($this->speakers)) {
return $this->speakers;
}
$this->logger->info("creating speaker instances");
$cacheKey = $this->getCacheKey();
if ($this->cache->contains($cacheKey)) {
$this->logger->info("getting device info from cache");
$devices = $this->cache->fetch($cacheKey);
} else {
$devices = $this->getDevices();
# Only cache the devices if we actually found some
if (count($devices) > 0) {
$this->cache->save($cacheKey, $devices);
}
}
if (count($devices) < 1) {
throw new \RuntimeException("No devices found on the current network");
}
# Get the topology information from 1 speaker
$topology = [];
$ip = reset($devices);
$uri = "http://{$ip}:1400/status/topology";
$this->logger->notice("Getting topology info from: {$uri}");
$xml = (string) (new Client())->get($uri)->getBody();
$players = (new XmlParser($xml))->getTag("ZonePlayers")->getTags("ZonePlayer");
foreach ($players as $player) {
$attributes = $player->getAttributes();
$ip = parse_url($attributes["location"])["host"];
$topology[$ip] = $attributes;
}
$this->speakers = [];
foreach ($devices as $ip) {
$device = new Device($ip, $this->cache, $this->logger);
if (!$device->isSpeaker()) {
continue;
}
$speaker = new Speaker($device);
if (!isset($topology[$ip])) {
throw new \RuntimeException("Failed to lookup the topology info for this speaker");
}
$speaker->setTopology($topology[$ip]);
$this->speakers[$ip] = $speaker;
}
return $this->speakers;
}