Example #1
0
 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
Example #2
0
    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
Example #4
0
 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
Example #5
0
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
Example #6
0
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
Example #8
0
    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
Example #9
0
        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()])
Example #10
0
    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")
Example #11
0
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()
Example #13
0
    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()
Example #14
0
 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([])
Example #15
0
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
Example #16
0
 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
Example #17
0
    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
Example #18
0
    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()
Example #19
0
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()
Example #20
0
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)
Example #21
0
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
Example #22
0
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
Example #24
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
Example #25
0
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
Example #26
0
 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)
Example #27
0
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
Example #28
0
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
Example #29
0
    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
Example #30
0
    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
Example #31
0
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)
Example #32
0
    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()
Example #33
0
def all_speakers(action):
    zones = soco.discover()
    for zone in zones:
        if action == 'play':
            zone.play()
        elif action == 'stop':
            zone.stop()
Example #34
0
  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
Example #35
0
 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]
Example #36
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
Example #37
0
 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)
Example #38
0
 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    
Example #39
0
	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
Example #40
0
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
Example #41
0
    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
Example #42
0
 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
Example #43
0
 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
Example #44
0
    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)
Example #45
0
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)
Example #46
0
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)
Example #48
0
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
Example #50
0
    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()
Example #51
0
 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
Example #52
0
	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])
Example #53
0
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'
Example #54
0
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
Example #55
0
 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
Example #56
0
    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()
Example #57
0
    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
Example #58
0
 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)
Example #59
0
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