def __init__(self, spotify_refresh_token=None, speaker_index=None, locale=None): # find the device devices = soco.discover() if devices is None or len(list(devices)) == 0: time.sleep(1) devices = soco.discover() if devices is None or len(list(devices)) == 0: return try: speaker_index = int(speaker_index) except Exception: speaker_index = 0 if speaker_index >= len(list(devices)): speaker_index = 0 self.device = list(devices)[speaker_index] try: self.tunein_service = MusicService('TuneIn') except Exception: self.tunein_service = None try: self.spotify_service = MusicService('Spotify') except Exception: self.spotify_service = None self.max_volume = MAX_VOLUME if spotify_refresh_token is not None: self.spotify = SpotifyClient(spotify_refresh_token) self.previous_volume = None
def play_spoken_notifications(self, notifications=None): notification_mp3s = [] for notification in notifications: tts = gTTS(text=notification, lang=self.tts_lang) now = datetime.datetime.now() filename = now.strftime('%Y-%m-%d_%H-%M-%S-%f') + ".mp3" notification_mp3s.append(filename) tts.save(self.webserver_path + filename) if notification_mp3s: group_coordinator = None for zone in list(soco.discover()): if zone.group.coordinator.player_name == zone.player_name: group_coordinator = zone zone_snapshot = Snapshot(zone) zone_snapshot.snapshot() time.sleep(1) zone.volume = int(self.volume) for mp3 in notification_mp3s: self.log.info('Playing notification ' + mp3 + ' on ' + zone.player_name) zone.play_uri(uri='http://' + Nic().get_current_address() + ':' + self.webserver_port + '/' + mp3) time.sleep(self.max_notification_seconds) zone_snapshot.restore() if group_coordinator is not None: for zone in list(soco.discover()): if zone.group.coordinator.player_name != zone.player_name: print zone.player_name + ' joining ' + zone.group.coordinator.player_name zone.join(group_coordinator) return notifications
def __init__(self, ui, appWidget, args): if args.noSonos == 'hasSonos': if args.host == 'host': self.myZone = list( soco.discover(timeout=5, include_invisible=False, interface_addr='192.168.1.118')) else: self.myZone = list(soco.discover()) self.activeSpeaker = 0 self.__Widget = appWidget
def zones(self): selected = self.config.get("zones", []) if self._zones_cached != selected: if len(selected) == 0: zones = list(soco.discover()) else: zones = [ zone for zone in soco.discover() if zone.get_speaker_info()["serial_number"] in selected ] self._zones = zones self._zones_cached = selected return self._zones
def listAvailableDevices(): d = {} if (soco.discover()): for zone in soco.discover(): d[zone.player_name] = {} d[zone.player_name]['zone.player_name'] = zone.player_name d[zone.player_name]['zone.uid'] = zone.uid d[zone.player_name]['zone.volume'] = zone.volume d[zone.player_name]['zone.is_coordinator'] = zone.is_coordinator response = jsonify({'devices': d}), status.HTTP_200_OK else: response = jsonify({'status': 'no devices found' }), status.HTTP_504_GATEWAY_TIMEOUT return response
def menu(): for zone in soco.discover(): def _mute(): mute(zone) yield pystray.MenuItem(text=zone.player_name, action=_mute)
def discoverAll(): if len(my_globals["Speakers"]) == 0: my_globals["Speakers"] = list(soco.discover()) elif my_globals["somethingChange"] == True: my_globals["somethingChange"] = False newList = list(soco.discover()) print "Rediscover" oldList = my_globals["Speakers"] newNewList = [] for oldItem in oldList: for newItem in newList: if newItem == oldItem: newNewList.append(newItem) my_globals["Speakers"] = newNewList else: pass
def discover(self) -> Set[Speaker]: """Discovers local Sonos speakers :returns: Set of discovered speakers :rtype: set[models.speaker.Speaker] """ speakers = set() speaker: soco.SoCo discovery = soco.discover(include_invisible=True) if discovery is not None: for speaker in discovery: name = speaker.player_name speaker_instance = Speaker(speaker_id=speaker.uid, name=name, ip_address=speaker.ip_address) if not speaker.is_visible and len({ x for x in speaker.group if x.is_visible and x.player_name == name }) == 1: speaker_instance.name = name + ' (R)' elif len(self.get_stereo_pair_slaves(speaker)) == 1: speaker_instance.name = name + ' (L)' speakers.add(speaker_instance) return speakers
async def discover(request): zones = self.config.get("zones", []) return json([{ **speaker.get_speaker_info(), "selected": bool(speaker.get_speaker_info()["serial_number"] in zones) } for speaker in soco.discover()])
def _loop(self): self.players = list(soco.discover() or []) # Go into party mode immediately if not already in it. if self.players and len(self.players[0].group.members) != len(self.players): self.players[0].partymode() self.player = self.players[0].group.coordinator while self.running: try: status = self._fetch_status() if status: self.status_queue.put(status) try: command = self.command_queue.get(True, STATUS_POLL_INTERVAL) self._process_command(command) except Queue.Empty: # No problem, ignore. pass except BaseException as e: # Probably connection error. Wait a bit and try again. self.logger.warning("Got exception in Sonos thread: %s" % e) time.sleep(60) self.logger.info("Exiting Sonos loop")
def line_in(): speakers = {s.player_name: s for s in soco.discover()} speakers['Josh'].unjoin() speakers['Josh'].switch_to_line_in() speakers['Josh'].play() speakers['Josh'].volume = 70
def motion_detected(): log.debug(f"{datetime.datetime.now()}: Motion detected...") # cancel timer, so we can properly start the music timer.cancel() # start the music try: all_sonos = set() for i in range(5): try: all_sonos = soco.discover() break except Exception as e: log.error( f"Attempt {i}: Can't find any Sonos players ({str(e)}), waiting..." ) time.sleep(5) log.debug( f"{datetime.datetime.now()}: {len(all_sonos)} Sonos players detected" ) for sonos in all_sonos: if sonos.is_coordinator: sonos.play() except Exception as e: log.error(f"{datetime.datetime.now()}: {str(e)}") finally: # make sure to exit application after music was started exit_application()
def __init__(self): self.devs = list(soco.discover()) self.dev = self.devs[0] self.groups = list(self.dev.all_groups) self.event_state = State() self.startEventThreads()
def __run_discovery(self): """Background Sonos discovery and handler, runs in executor thread.""" if self._discovery_running: return self._discovery_running = True LOGGER.debug("Sonos discovery started...") discovered_devices = soco.discover() if discovered_devices is None: discovered_devices = [] new_device_ids = [item.uid for item in discovered_devices] cur_player_ids = [item.player_id for item in self._players.values()] # remove any disconnected players... for player in list(self._players.values()): if not player.is_group and player.soco.uid not in new_device_ids: self.mass.add_job( self.mass.players.remove_player(player.player_id)) for sub in player.subscriptions: sub.unsubscribe() self._players.pop(player, None) # process new players for device in discovered_devices: if device.uid not in cur_player_ids and device.is_visible: self.__device_discovered(device) # handle groups if len(discovered_devices) > 0: self.__process_groups(discovered_devices[0].all_groups) else: self.__process_groups([])
def main(): zones = list(soco.discover()) zones.sort(key=lambda zone: zone.ip_address) zone = zones[0] print "Sonos zone: %s" % zone.player_name monitor = PeakMonitor(SINK_NAME, METER_RATE) sounding = False blank_time = 0 for sample in monitor: if sample > 1: blank_time = 0 if not sounding: sounding = True print "Now sounding" track = zone.get_current_track_info() transport = zone.get_current_transport_info() if transport["current_transport_state"] == "STOPPED" or track[ "uri"] != RADIO_URI: print "Tuning in" zone.play_uri(RADIO_URI) else: blank_time += 1 if sounding and blank_time > 5 * METER_RATE: print "Not sounding anymore" sounding = False
def get_options(self): self.display.displayLoadingAnimation() self.players = {} for i in soco.discover(): self.players[i.player_name] = i self.display.stopLoadingAnimation() return self.players
def __init__(self): '''Initiate class with all zones in the Sonos system if IP given use that zone to extract details, otherwise use discover to find zones and use one. ''' starter_zp = None while starter_zp is None: my_zones = list(soco.discover()) if len(my_zones) > 0: starter_zp = my_zones[0] # grab first IP found else: # caters for network not responding or busy print ("Warning - not discovered any zone players! - trying again") sleep(1) # get zone player topology by querying one IP (all ZPs hold the full topology) zone_count = self._set_topology(starter_zp) if zone_count > 0: # found at least one zone print ('...found %d zones' % (zone_count)) # add all the soco instances to topology for found_soco in my_zones: found_ip = found_soco.__dict__['ip_address'] self.topology[found_ip]['soco'] = found_soco
def start_subs(): logging.basicConfig(level=logging.ERROR) # pick a device device = soco.discover().pop() # Subscribe to ZGT events sub = device.zoneGroupTopology.subscribe() # print out the events as they arise t_end = time.time() + 60 * 2 while time.time() < t_end: try: event = sub.events.get(timeout=0.5) pp = pprint.PrettyPrinter(indent=4) pp.pprint(event.variables) except Empty: pass except KeyboardInterrupt: print("exiting KeyboardInterrupt") sub.unsubscribe() event_listener.stop() break except EOFError: print("exiting EOFError") sub.unsubscribe() event_listener.stop() break print("exiting loop") sub.unsubscribe()
def add_random_file_from_present_folder(machine_ip, port, zone_name): """Add a random non-py file from this folder and subfolders to soco""" # Make a list of music files, right now it is done by collection all files # below the current folder whose extension does not start with .py # This will probably need to be modded for other pusposes. music_files = [] print('Looking for music files') for path, dirs, files in os.walk('.'): for file_ in files: if not os.path.splitext(file_)[1].startswith('.py'): music_files.append(os.path.relpath(os.path.join(path, file_))) print('Found:', music_files[-1]) random_file = choice(music_files) # urlencode all the path parts (but not the /'s) random_file = os.path.join( *[quote(part) for part in os.path.split(random_file)] ) print('\nPlaying random file:', random_file) netpath = 'http://{}:{}/{}'.format(machine_ip, port, random_file) for zone in soco.discover(): if zone.player_name == zone_name: break number_in_queue = zone.add_uri_to_queue(netpath) zone.play_from_queue(number_in_queue)
def say(sentence): if sys.platform == "darwin": # only if we are in a Mac if se_puede_hablar(): # asks for output devices say_output = subprocess.check_output(["say", "-a", "?"]) for line in say_output.split("\n"): if built_in_pattern.search(line): numero = number_pattern.search(line) if numero: """ subprocess.call(["say", "-a", numero.group(0), "-o", "/Users/jmalmellones/Desktop/public/temp.m4a", sentence]) """ subprocess.call([ "say", "-o", "/Users/jmalmellones/Desktop/public/temp.m4a", sentence ]) list(soco.discover())[0].play_uri( 'http://192.168.1.41:8080/temp.m4a') break return print "say: ", sentence
def scan(): zones = soco.discover() print "SONOS" + "\n" + "-----" for zone in zones: transport_info = zone.get_current_transport_info() # zone.get_speaker_info().get('hardware_version') if True is True: print "{}: {}, {}, {}, {}, IP={}".format( zone.uid, zone.player_name, transport_info['current_transport_status'], transport_info['current_transport_state'], transport_info['current_transport_speed'], zone.ip_address ) print "\n" + "YAMAHA" + "\n" + "------" receivers = rxv.find() for rx in receivers: uri = urlparse(rx.ctrl_url) print "{}: {} ({})\n\t\t{}\n\t\t{}".format( uri.hostname, rx.friendly_name, rx.model_name, rx.ctrl_url, rx.basic_status)
def find_controller(name): for s in list(soco.discover()): if s.player_name != name: continue ip = s.group.coordinator.ip_address return soco.SoCo(ip) return None
def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the Sonos platform. """ import soco import socket if discovery_info: add_devices([SonosDevice(hass, soco.SoCo(discovery_info))]) return True players = None hosts = config.get('hosts', None) if hosts: players = [] for host in hosts.split(","): host = socket.gethostbyname(host) players.append(soco.SoCo(host)) if not players: players = soco.discover( interface_addr=config.get('interface_addr', None)) if not players: _LOGGER.warning('No Sonos speakers found.') return False add_devices(SonosDevice(hass, p) for p in players) _LOGGER.info('Added %s Sonos speakers', len(players)) return True
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Sonos platform.""" import soco import socket if discovery_info: add_devices([SonosDevice(hass, soco.SoCo(discovery_info))]) return True players = None hosts = config.get('hosts', None) if hosts: # Support retro compatibility with comma separated list of hosts # from config hosts = hosts.split(',') if isinstance(hosts, str) else hosts players = [] for host in hosts: players.append(soco.SoCo(socket.gethostbyname(host))) if not players: players = soco.discover(interface_addr=config.get('interface_addr', None)) if not players: _LOGGER.warning('No Sonos speakers found.') return False add_devices(SonosDevice(hass, p) for p in players) _LOGGER.info('Added %s Sonos speakers', len(players)) return True
def get_zone_names(): ''' Returns a sorted list of zone names ''' zone_list = list(soco.discover()) zone_names = [] for zone in zone_list: zone_names.append(zone.player_name) return sorted(zone_names)
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Sonos platform.""" import soco if discovery_info: player = soco.SoCo(discovery_info) if player.is_visible: add_devices([SonosDevice(hass, player)]) return True return False players = None hosts = config.get('hosts', None) if hosts: # Support retro compatibility with comma separated list of hosts # from config hosts = hosts.split(',') if isinstance(hosts, str) else hosts players = [] for host in hosts: players.append(soco.SoCo(socket.gethostbyname(host))) if not players: players = soco.discover(interface_addr=config.get('interface_addr', None)) if not players: _LOGGER.warning('No Sonos speakers found.') return False add_devices(SonosDevice(hass, p) for p in players) _LOGGER.info('Added %s Sonos speakers', len(players)) return True
def main(): zones = list(soco.discover()) zones.sort(key = lambda zone: zone.ip_address) zone = zones[0] print "Sonos zone: %s" % zone.player_name monitor = PeakMonitor(SINK_NAME, METER_RATE) sounding = False blank_time = 0 for sample in monitor: if sample > 1: blank_time = 0 if not sounding: sounding = True print "Now sounding" track = zone.get_current_track_info() transport = zone.get_current_transport_info() if transport["current_transport_state"] == "STOPPED" or track["uri"] != RADIO_URI: print "Tuning in" zone.play_uri(RADIO_URI) else: blank_time += 1 if sounding and blank_time > 5*METER_RATE: print "Not sounding anymore" sounding = False
def getAll(self): speakers = soco.discover() self.data = {} speaker_data = [] for speaker in speakers: speaker_info = speaker.get_speaker_info() speaker_data.append({ 'name' : speaker.player_name, 'ip_address' : speaker.ip_address, 'mac_address' : speaker_info['mac_address'], 'software_version' : speaker_info['software_version'], 'hardware_version' : speaker_info['hardware_version'], 'display_version' : speaker_info['display_version'], 'icon' : speaker_info['player_icon'], 'uniqueid' : speaker.uid, 'mute' : speaker.mute, 'volume' : speaker.volume, 'status_light' : speaker.status_light, 'serial_number' : speaker_info['serial_number'], 'model_name' : speaker_info['model_name'], }) return speaker_data
def power(self): speaker_data = {} if (self.ip != None): speakers = soco.discover() speaker_exists = False for speaker in speakers: if(self.ip == speaker.ip_address): speaker_exists = True if(speaker_exists == True): speaker = soco.SoCo(self.ip) else: speaker_data = { 'status' : 503, 'msg' : 'Sonos speaker are unavailable.' } else: speaker_data = { 'status' : 404, 'msg' : 'You need to defined the ip to the speaker you will connect to.' } return speaker_data
def add_random_file_from_present_folder(machine_ip, port, zone_name): """Add a random non-py file from this folder and subfolders to soco""" # Make a list of music files, right now it is done by collection all files # below the current folder whose extension does not start with .py # This will probably need to be modded for other pusposes. music_files = [] print('Looking for music files') for path, dirs, files in os.walk('.'): for file_ in files: if not os.path.splitext(file_)[1].startswith('.py'): music_files.append(os.path.relpath(os.path.join(path, file_))) print('Found:', music_files[-1]) random_file = choice(music_files) # urlencode all the path parts (but not the /'s) random_file = os.path.join( *[quote(part) for part in os.path.split(random_file)]) print('\nPlaying random file:', random_file) netpath = 'http://{}:{}/{}'.format(machine_ip, port, random_file) for zone in soco.discover(): if zone.player_name == zone_name: break number_in_queue = zone.add_uri_to_queue(netpath) zone.play_from_queue(number_in_queue)
def setup(self): self._options = {} config = self._db.pq( """SELECT name, value FROM options WHERE name IN ('sonos_url', 'sonos_port', 'sonos_aa')""" ) if config: for row in config: self._options[row["name"]] = row["value"] self._devices = [] for device in soco.discover(): node = SonosDeviceNode( self._homie, device.get_speaker_info()["zone_name"], self.client, self._options, ) self._homie.nodes.append(node) self._devices.append(node) self._sonos = self._homie.Node("sonos", "sonos") self._sonos.advertise("favourites") self._sonos.advertise("pause").settable(self.pause_handler) self._sonos.advertise("resume").settable(self.resume_handler) self._zones = self._homie.Node("zones", "zones") self._zones.advertise("current") self._zones.advertise("add").settable(self.add_to_zone_handler) self._zones.advertise("remove").settable(self.remove_from_zone_handler) self._zones.advertise("volume").settable(self.volume_handler) self._update_running = True self._update_thread = threading.Thread(target=self._update) self._update_thread.daemon = True self._update_thread.start()
def all_speakers(action): zones = soco.discover() for zone in zones: if action == 'play': zone.play() elif action == 'stop': zone.stop()
def _scan_once(self): devices = soco.discover() if devices is None: return devices = list(devices) logging.info('Found %d sonos devices.', len(devices)) for device in devices: uid = device.uid self._devices[uid] = device speaker_info = device.get_speaker_info() currently_playing = device.get_current_track_info() current_transport_info = device.get_current_transport_info() details = { 'uid': uid, 'device_name': speaker_info['zone_name'], 'currently_playing': {k: currently_playing.get(k, None) for k in CURRENTLY_PLAYING_KEYS}, 'state': current_transport_info['current_transport_state'], } if self._previous_details.get(uid, None) != details: self._callback('sonos', 'sonos-%s' % uid, details) self._previous_details[uid] = details
def __init__(self): self.group_id = active_group_store.get_active_group() self.playing_id = None self.playing_type = None self.playing_shuffle = False self.paused = False self.soco = list(soco.discover())[0]
def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the Sonos platform. """ import soco import socket if discovery_info: add_devices([SonosDevice(hass, soco.SoCo(discovery_info))]) return True players = None hosts = config.get('hosts', None) if hosts: players = [] for host in hosts.split(","): host = socket.gethostbyname(host) players.append(soco.SoCo(host)) if not players: players = soco.discover(interface_addr=config.get('interface_addr', None)) if not players: _LOGGER.warning('No Sonos speakers found.') return False add_devices(SonosDevice(hass, p) for p in players) _LOGGER.info('Added %s Sonos speakers', len(players)) return True
def scan_speakers(self): speakers = soco.discover() if not speakers: return logging.debug("No speakers found") speakers = list(speakers) logging.debug('Found %d speaker(s)', len(speakers)) [s.get_speaker_info() for s in speakers] self.add_speakers(speakers)
def get_addr(self,hks): players = list(soco.discover()) p_name = self.Devices_neu[hks] for player in players: if player._player_name == p_name: ip = player.ip_address uid = player.uid return ip, uid, p_name
def onStart(self): super().onStart() self._sonosPlayers = {device.player_name.lower(): device for device in soco.discover()} if not self._sonosPlayers: self.logWarning('No Sonos device found') raise SkillStartingFailed
def find_speaker(speaker_name): speakers = soco.discover() for speaker in speakers: if speaker.player_name == speaker_name: return speaker if not speakers: print "Speaker not found" return False
def get_zone_by_name(zoneName): '''Returns a SoCo instance if found, or None if not found''' zone_list = list(soco.discover()) for zone in zone_list: if zone.player_name == zoneName: return zone return None
def user_select_zone(self): # get user input if no zone name defined zone_names = [zone.player_name for zone in soco.discover()] print zone_names self.cfg['desired_zone'] = raw_input('Which zone would you like to troll?\n') if not self.cfg['desired_zone'] in list(zone_names): print self.cfg['desired_zone'], 'is not an option' self.cfg['desired_zone'] = None
def zones(self): if not self.__zone_ip: if not self._zones: self._zones = soco.discover(timeout=5) else: logging.info("Discovering with custom IP") self._zones = [soco.SoCo(self.__zone_ip)] return self._zones
def discoverer(self): def addOrReplaceZone(zone): if zone.player_name in self.zones: if zone.ip_address != self.zones[zone.player_name].ip_address: with self.zlock: self.zones.pop(zone.player_name) self.logger.debug("Replacing: %s"%zone.player_name) else: self.logger.debug("Unchanged: %s"%zone.player_name) return else: self.logger.info("Adding: %s"%zone.player_name) with self.zlock: self.zones[zone.player_name] = zone def removeZone(zone_name): if zone_name in self.zones: with self.zlock: self.zones.pop(zone_name) self.logger.info("Expiring: %s"%zone_name) while not self.quit: zones_needed = list(self.needed_zones) self.logger.debug("Need to find these zones: %s" %zones_needed) zones_discovered = discover(10) for z in list(zones_discovered): addOrReplaceZone(z) try: zones_needed.remove(z.player_name) except ValueError: self.logger.debug("Did not want: %s" %z.player_name) for z in zones_needed: removeZone(z) if len(zones_needed) > 0: self.logger.warning("Missing zones: %s" % zones_needed) self.logger.warning("New attempt in 5 sec...") for x in range(0,5): if self.quit: break sleep(1) else: self.logger.debug("Found all needed zones: %s" %self.zones.keys()) self.logger.debug("New check in 60 sec...") for x in range(0,60): if self.quit: break sleep(1)
def _sonos_refresh(): global coordinator groups.clear() speakers = soco.discover() if speakers: for speaker in speakers: groups[speaker.group.coordinator].append(speaker) coordinator = None if len(groups) != 1 else groups.keys()[0] return bool(speakers)
def configure_sonos(config): import soco sonos = soco.discover() config.registry['sonos'] = sonos config.add_request_method( lambda r: r.registry['sonos'], 'sonos', property=True )
def discover_target_sonos_player(target_name): zones = soco.discover() if zones == None: print "No Sonos players discovered on this network." else: for zone in zones: if zone.player_name == target_name: return zone raise UndiscoverablePlayerError(target_name)
def find_random_player(): """Searches the network for Sonos zones and picks one randomly""" zones = soco.discover() if zones: # picking a random player player = next(iter(zones)) return player return None
def startSonos(self, speaker): # Sonos setup MusicLogging.Instance().info("Connecting to Sonos...") self.speakers = soco.discover() try: self.sonosDevice = soco.discovery.by_name(speaker) except: self.sonosDevice = self.speakers.pop() return True
def __init__(self, parent): ttk.Frame.__init__(self, parent) self.parent = parent self.lstSonos = list(sonosLib.discover()) self.sonos = self.lstSonos[0] self.counter = 0 self.initUI()
def get_device_list(cls, retries_remaining=3): try: devices = list(soco.discover()) assert len(devices) > 0 return devices except (AssertionError, TypeError): if retries_remaining > 0: return cls.get_device_list(retries_remaining - 1) else: raise
def GET(self): web.header('Content-Type', 'application/json') web.header('Access-Control-Allow-Origin', '*') web.header('Access-Control-Allow-Credentials', 'true') deviceList = [] for zone in soco.discover(): o = SonosDevice(zone.player_name, zone.ip_address) deviceList.append(o) return json.dumps([item.toJSON() for item in deviceList])
def tts_phrase(): zones = {zone.player_name: zone for zone in soco.discover()} data = request.get_data() if isinstance(data, str): # handle jquery nonsense data = json.loads(data) zone = zones[data['zone']] text = data['text'] speech = Speech(zone) speech.say(text) return 'success'
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Sonos platform.""" import soco if discovery_info: player = soco.SoCo(discovery_info) if player.is_visible: add_devices([SonosDevice(hass, player)]) return True return False players = None hosts = config.get('hosts', None) if hosts: # Support retro compatibility with comma separated list of hosts # from config hosts = hosts.split(',') if isinstance(hosts, str) else hosts players = [] for host in hosts: players.append(soco.SoCo(socket.gethostbyname(host))) if not players: players = soco.discover(interface_addr=config.get('interface_addr', None)) if not players: _LOGGER.warning('No Sonos speakers found.') return False devices = [SonosDevice(hass, p) for p in players] add_devices(devices) _LOGGER.info('Added %s Sonos speakers', len(players)) def group_players_service(service): """Group media players, use player as coordinator.""" entity_id = service.data.get('entity_id') if entity_id: _devices = [device for device in devices if device.entity_id == entity_id] else: _devices = devices for device in _devices: device.group_players() device.update_ha_state(True) descriptions = load_yaml_config_file( path.join(path.dirname(__file__), 'services.yaml')) hass.services.register(DOMAIN, SERVICE_GROUP_PLAYERS, group_players_service, descriptions.get(SERVICE_GROUP_PLAYERS)) return True
def durchsage(self,text): success = False players = list(soco.discover()) while not success: try: self.Status = {} # print self.Status # save all zones for player in players: t = threading.Thread(target=self.soco_get_status, args = [player]) t.start() # print self.Status mustend = time.time() + 5 while (len(self.Status) < len(players)) and (time.time() < mustend): time.sleep(0.25) success = True except: pass # combine all zones success = False while not success: try: for player in players: if 'S1' in player.get_speaker_info()[u'model_number']: self.SetVolume(player.ip_address, 10) elif 'ZP90' in player.get_speaker_info()[u'model_number']: self.SetVolume(player.ip_address, 65) elif 'ZP120' in player.get_speaker_info()[u'model_number']: self.SetVolume(player.ip_address, 40) soco.SoCo('192.168.192.203').partymode() mustend = time.time() + 5 while (not len(soco.SoCo('192.168.192.203').all_groups) == 2) and (time.time() < mustend): time.sleep(0.25) # time.sleep(2) # source to PC soco.SoCo('192.168.192.203').switch_to_line_in() mustend = time.time() + 5 while (not soco.SoCo('192.168.192.203').is_playing_line_in) and (time.time() < mustend): time.sleep(0.25) soco.SoCo('192.168.192.203').play() mustend = time.time() + 5 while (not soco.SoCo('192.168.192.203').get_current_transport_info()['current_transport_state'] == 'PLAYING') and (time.time() < mustend): time.sleep(0.25) success = True except: pass # play file or text on PC play_wav(text) # resume all playback for player in players: player.unjoin() self.soco_set_status(player) return True
def __init__(self): self.players = soco.discover() for player in self.players: if player.is_coordinator: self.coordinator = player self.state = 'UNKNOWN' self.eventReceiver = EventReceiver(self.coordinator, self._on_state_change) self.eventReceiver.start()
def test_discover(self, mock_soco, mock_select, mock_socket): socket = mock_socket.return_value socket.recvfrom.return_value = (b'SERVER: Linux UPnP/1.0 Sonos/26.1-76230 (ZPS3)', [IP_ADDR]) # (data, # address) mock_select.return_value = (1, 1, 1) # set timeout TIMEOUT = 5 discover(timeout=TIMEOUT) # 3 packets should be sent assert socket.sendto.call_count == 3 # select called with the relevant timeout mock_select.assert_called_once_with([socket], [], [], min(TIMEOUT, 0.1)) # SoCo should be created with the IP address received mock_soco.assert_called_with(IP_ADDR) # Now test include_visible parameter. include_invisible=True should # result in calling SoCo.all_zones etc mock_soco.return_value = Mock(all_zones='ALL', visible_zones='VISIBLE') assert discover(include_invisible=True) == 'ALL' assert discover(include_invisible=False) == 'VISIBLE' # if select does not return within timeout SoCo should not be called # at all # simulate no data being returned within timeout mock_select.return_value = (0, 1, 1) discover() # Check no SoCo instance created mock_soco.assert_not_called
def __init__(self): self.players = soco.discover() if self.players is None or len(self.players) == 0: raise Exception('No Sonos players found') # get default player from config try: self.default = soco.SoCo(resources.user.read('sonosplayer.ip')) except TypeError as e: self.default = None if self.default is None and len(self.players) == 1: # no default sonos speaker set self.default = self.players.pop() # only one player found, set it as default self.setPlayer(self.default)
def setup_platform(hass, config, add_devices, discovery_info=None): """ Sets up the Sonos platform. """ import soco players = soco.discover() if not players: _LOGGER.warning('No Sonos speakers found. Disabling: %s', __name__) return False add_devices(SonosDevice(hass, p) for p in players) _LOGGER.info('Added %s Sonos speakers', len(players)) return True