Exemple #1
0
    def find(self, speaker_name, require_visible=True):
        """Find a speaker by name and return its SoCo object."""

        speaker_names = set()
        return_speaker = None

        for speaker in self._speakers:
            if require_visible and not speaker.is_visible:
                continue

            match, exact = speaker_name_matches(speaker_name,
                                                speaker.speaker_name)

            if match and exact:
                speaker_names.add(speaker.speaker_name)
                return soco.SoCo(speaker.ip_address)

            if match and not exact:
                speaker_names.add(speaker.speaker_name)
                if not return_speaker:
                    return_speaker = soco.SoCo(speaker.ip_address)

        if len(speaker_names) > 1:
            print("Speaker name '{}' is ambiguous within {}".format(
                speaker_name, speaker_names))
            return None

        return return_speaker
Exemple #2
0
 def find(self, speaker_name, require_visible=True):
     """Find a speaker by name and return its SoCo object."""
     # Normalise apostrophes
     speaker_name = speaker_name.replace("’", "'")
     # Check for exact match first
     for speaker in self._speakers:
         # Normalise apostrophes
         s = speaker.speaker_name.replace("’", "'")
         if speaker_name == s:
             if require_visible:
                 if speaker.is_visible:
                     logging.info(
                         "Found exact speaker name match for '{}'".format(
                             speaker.speaker_name
                         )
                     )
                     return soco.SoCo(speaker.ip_address)
             else:
                 return soco.SoCo(speaker.ip_address)
     # Check for partial, case insensitive match if no exact match
     for speaker in self._speakers:
         # Normalise apostrophes
         s = speaker.speaker_name.replace("’", "'")
         if speaker_name.lower() in s.lower():
             if require_visible:
                 if speaker.is_visible:
                     logging.info(
                         "Found fuzzy speaker name match for '{}'".format(
                             speaker.speaker_name
                         )
                     )
                     return soco.SoCo(speaker.ip_address)
             else:
                 return soco.SoCo(speaker.ip_address)
     return None
Exemple #3
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
Exemple #4
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
Exemple #5
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
Exemple #6
0
def kitchen(switch):
    if switch == "on":
        soco.SoCo("192.168.1.134").balance = (0, 100)
        soco.SoCo("192.168.1.134").play()
        print("family room should be playing music now...")
        return True
    elif switch == "off":
        soco.SoCo("192.168.1.134").stop()
        print("family room turned off...")
        return True
    else:
        print("Error in option choice")
        return False
Exemple #7
0
def master_bedroom():
    if switch == "on":
        soco.SoCo("192.168.1.127").balance = (100, 0)
        soco.SoCo("192.168.1.127").play()
        print("guest room should be playing music now...")
        return True
    elif switch == "off":
        soco.SoCo("192.168.1.127").stop()
        print("guest room turned off...")
        return True
    else:
        print("Error in option choice")
        return False
Exemple #8
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the Sonos platform."""
    import soco
    global DEVICES

    advertise_addr = config.get(CONF_ADVERTISE_ADDR, None)
    if advertise_addr:
        soco.config.EVENT_ADVERTISE_IP = advertise_addr

    if discovery_info:
        player = soco.SoCo(discovery_info)

        # if device allready exists by config
        if player.uid in [x.unique_id for x in DEVICES]:
            return True

        if player.is_visible:
            device = SonosDevice(hass, player)
            add_devices([device], True)
            if not DEVICES:
                register_services(hass)
            DEVICES.append(device)
            return True
        return False

    players = None
    hosts = config.get(CONF_HOSTS, None)
    if hosts:
        # Support retro compatibility with comma separated list of hosts
        # from config
        hosts = hosts[0] if len(hosts) == 1 else hosts
        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(CONF_INTERFACE_ADDR))

    if not players:
        _LOGGER.warning('No Sonos speakers found.')
        return False

    DEVICES = [SonosDevice(hass, p) for p in players]
    add_devices(DEVICES, True)
    register_services(hass)
    _LOGGER.info('Added %s Sonos speakers', len(players))
    return True
Exemple #9
0
    def get_volume(self, speaker: Speaker) -> int:
        """Gets volume of passed Sonos speaker

        :param models.speaker.Speaker speaker: Speaker for which the volume gets requested
        """
        soco_instance = soco.SoCo(speaker.ip_address)
        return soco_instance.volume
Exemple #10
0
def soco():
    """ Set up and tear down the soco fixture used by all tests. """
    # Get the ip address from the command line, and create the soco object
    # Only one is used per test session, hence the decorator
    ip = pytest.config.option.IP
    if ip is None:
        pytest.fail("No ip address specified. Use the --ip option.")
    soco = soco_module.SoCo(ip)
    # Check the device is playing and has items in the queue
    if len(soco.get_queue()) == 0:
        pytest.fail('Integration tests on the SoCo class must be run '
                    'with at least 1 item in the playlist.')

    transport_info = soco.get_current_transport_info()
    if transport_info['current_transport_state'] != 'PLAYING':
        pytest.fail('Integration tests on the SoCo class must be run '
                    'with the Sonos unit playing.')
    # Save the device's state
    state = {'queue': soco.get_queue(0, 1000),
             'current_track_info': soco.get_current_track_info()}

    # Yield the device to the test function
    yield soco

    # Tear down. Restore state
    soco.stop()
    soco.clear_queue()
    for track in state['queue']:
        soco.add_to_queue(track['uri'])
    soco.play_from_queue(
        int(state['current_track_info']['playlist_position']) - 1)
    soco.seek(state['current_track_info']['position'])
    soco.play()
Exemple #11
0
def main():
    """ Run the main script """
    parser = argparse.ArgumentParser(
        prog='',
        description='Dump data about Sonos services'
    )
    parser.add_argument(
        '-d', '--device',
        default=None,
        help="The ip address of the device to query. "
             "If none is supplied, a random device will be used"
    )
    parser.add_argument(
        '-s', '--service',
        default=None,
        help="Dump data relating to services matching this regexp "
             "only, e.g. %(prog)s -s GroupRenderingControl"
    )

    args = parser.parse_args()

    # get a zone player - any one will do
    if args.device:
        device = soco.SoCo(args.device)
    else:
        device = soco.discovery.any_soco()
    print("Querying %s" % device.player_name)
    # loop over each of the available services
    # pylint: disable=no-member
    services = (srv(device) for srv in soco.services.Service.__subclasses__())

    for srv in services:
        if args.service is None or re.search(
                args.service, srv.service_type):
            print_details(srv)
Exemple #12
0
def soco(request):
    """Set up and tear down the soco fixture used by all tests."""
    # Get the ip address from the command line, and create the soco object
    # Only one is used per test session, hence the decorator
    ip = request.config.option.IP
    if ip is None:
        pytest.fail("No ip address specified. Use the --ip option.")
    soco_instance = soco_module.SoCo(ip)
    # Check the device is playing and has items in the queue
    if len(soco_instance.get_queue()) == 0:
        pytest.fail("Integration tests on the SoCo class must be run "
                    "with at least 1 item in the playlist.")

    transport_info = soco_instance.get_current_transport_info()
    if transport_info["current_transport_state"] != "PLAYING":
        pytest.fail("Integration tests on the SoCo class must be run "
                    "with the Sonos unit playing.")
    # Save the device's state
    state = {
        "queue": soco_instance.get_queue(0, 1000),
        "current_track_info": soco_instance.get_current_track_info(),
    }

    # Yield the device to the test function
    yield soco_instance

    # Tear down. Restore state
    soco_instance.stop()
    soco_instance.clear_queue()
    for track in state["queue"]:
        soco_instance.add_to_queue(track)
    soco_instance.play_from_queue(
        int(state["current_track_info"]["playlist_position"]) - 1)
    soco_instance.seek(state["current_track_info"]["position"])
    soco_instance.play()
Exemple #13
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
Exemple #14
0
def get_speaker(name, local=False):
    # Use an IP address
    # (Allow the use of an IP address even if 'local' is specified)
    if Speakers.is_ipv4_address(name):
        logging.info("Using IP address instead of speaker name")
        return soco.SoCo(name)

    # Use the local speaker list
    if local:
        logging.info("Using local speaker list")
        return speaker_list.find(name)

    # Use discovery
    # Try various lookup methods in order of expense,
    # and cache results where possible
    speaker = None
    if not speaker:
        logging.info("Trying direct cache lookup")
        speaker = SPKR_CACHE.find(name)
    if not speaker:
        logging.info("Trying indirect cache lookup")
        speaker = SPKR_CACHE.find_indirect(name)
    if not speaker:
        logging.info("Trying standard discovery with network scan fallback")
        SPKR_CACHE.discover()
        speaker = SPKR_CACHE.find(name)
    if not speaker:
        logging.info("Trying network scan discovery")
        SPKR_CACHE.scan()
        speaker = SPKR_CACHE.find(name)
    if speaker:
        logging.info("Successful speaker discovery")
    else:
        logging.info("Failed to discover speaker")
    return speaker
Exemple #15
0
    def monitor(self):
        soco.config.EVENT_LISTENER_PORT = self.cfg['sonos']['event_port']
        self.sonos = soco.SoCo(
            self.cfg['sonos']['ip'])
        self.yamaha = rxv.RXV(
            self.cfg['yamaha']['ctrl_url'], self.cfg['yamaha']['model_name'])

        self.log.info("{} ({}) Power={}, Input={}, Volume={}".format(
            self.cfg['yamaha']['friendly_name'],
            self.cfg['yamaha']['model_name'],
            self.yamaha.on, self.yamaha.input, self.yamaha.volume))

        signal(SIGTERM, self.handle_sigterm)

        while self.break_loop is False:
            self._subscription()
            try:
                self.event = self.subscription.events.get(timeout=10)
                self.status = self.event.variables.get('transport_state')
                self._status()
            except Queue.Empty:
                pass
            except KeyboardInterrupt:
                self.handle_sigterm()
                break

        if self.break_loop:
            self.subscription.unsubscribe()
            soco.events.event_listener.stop()
def test_ring_sonos(component_ip, hub_ip):  # pragma: no cover
    test_speaker = soco.SoCo(component_ip)
    if hub_ip is None:
        logger.error("Unable to extract Hub IP Address.")
        return False
    # The lighttpd server is configured to listen on port 81
    # Resource files are stored in /www/pages/resources .. (on the hub)
    port = 81
    uri_test = "http://" + hub_ip + ":" + str(
        port) + "/resources/swblaster.mp3"
    try:
        test_speaker.volume = 10
        test_speaker.play_uri(uri_test)
        test_speaker.get_current_track_info()
        time.sleep(2)
        test_speaker.stop()
        try:
            test_speaker.play_from_queue(0)
            test_speaker.stop()
        except soco.SoCoException:
            # No action required, as the queue is empty.
            pass
        return True

    except (soco.SoCoException, HTTPNotFound) as e:
        logger.error("Error while testing Sonos: " + str(e))
        return False
Exemple #17
0
 def get_all_speakers(self):
     soco_speakers = []
     for speaker in self._speakers:
         soco_speakers.append(soco.SoCo(speaker.ip_address))
     if soco_speakers:
         return soco_speakers
     return None
Exemple #18
0
    def __init__(self, name=None, sonos_ip=None, port=6060):
        self.machine_ip = self.detectIPAddress()
        self.port = port

        if name is None and sonos_ip is None:
            raise Exception("either name or sonos_ip must be provided")

        else:
            if name:
                device = soco.discovery.by_name(name)
            elif sonos_ip:
                device = soco.SoCo(sonos_ip)
            elif name and sonos_ip:
                device = soco.SoCo(sonos_ip)
                if device.player_name != name:
                    raise Exception("name does not match sonos_ip")

        self.device = device
Exemple #19
0
def pair_socos(l_ip, r_ip):
    l_soco = soco.SoCo(l_ip)
    r_soco = soco.SoCo(r_ip)

    l_uid = l_soco.uid
    r_uid = r_soco.uid

    req_addr = request_address_format.format(l_ip)
    req_headers = {
        "Content-Type": "application/xml",
        "SOAPAction": pair_soap_action,
    }
    req_payload = pair_payload_format.format(l_uid, r_uid)

    response = requests.post(req_addr, data=req_payload, headers=req_headers)

    if response.status_code != 200:
        print("failed to pair")
Exemple #20
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the Sonos platform."""
    import soco
    global DEVICES

    if discovery_info:
        player = soco.SoCo(discovery_info)

        # if device allready exists by config
        if player.uid in DEVICES:
            return True

        if player.is_visible:
            device = SonosDevice(hass, player)
            add_devices([device])
            if not DEVICES:
                register_services(hass)
            DEVICES.append(device)
            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)
    register_services(hass)
    _LOGGER.info('Added %s Sonos speakers', len(players))
    return True
Exemple #21
0
def get_speaker(name, local=False):
    # Allow the use of an IP address even if 'local' is specified
    if Speakers.is_ipv4_address(name):
        logging.info("Using IP address instead of speaker name")
        return soco.SoCo(name)
    if local:
        logging.info("Using local speaker list")
        return speaker_list.find(name)
    else:
        logging.info("Using SoCo speaker discovery")
        return soco.discovery.by_name(name)
Exemple #22
0
def precedente(hermes, intentMessage):
    conf = read_configuration_file(CONFIG_INI)
    current_session_id = intentMessage.session_id
    addr_ = conf['global']['ip']
    port_ = conf['global']['port']
    user_ = conf['global']['user']
    password_ = conf['global']['password']

    zone = soco.SoCo('192.168.10.4')
    zone.previous()

    hermes.publish_end_session(current_session_id, "OK")
Exemple #23
0
    def ramp_to_volume(self, speaker: Speaker, volume: int):
        """Ramps volume to target volume for the passed Sonos speaker

        :param models.speaker.Speaker speaker: Speaker to control
        :param int volume: Volume to ramp up or down to
        """
        soco_instance = soco.SoCo(speaker.ip_address)
        soco_slaves = list(self.get_stereo_pair_slaves(speaker))
        soco_slaves_volumes = [x.volume for x in soco_slaves]
        soco_instance.ramp_to_volume(volume)
        for index, slave in enumerate(soco_slaves):
            slave.volume = soco_slaves_volumes[index]
Exemple #24
0
    def set_volume(self, speaker: Speaker, volume: int):
        """Sets volume for passed Sonos speaker

        :param models.speaker.Speaker speaker: Speaker to control
        :param int volume: Volume to set
        """
        soco_instance = soco.SoCo(speaker.ip_address)
        soco_slaves = list(self.get_stereo_pair_slaves(speaker))
        soco_slaves_volumes = [x.volume for x in soco_slaves]
        soco_instance.volume = volume
        for index, slave in enumerate(soco_slaves):
            slave.volume = soco_slaves_volumes[index]
Exemple #25
0
    def get_coordinator_instance(self, speaker: Speaker) -> soco.SoCo:
        """Get the SoCo instance of the passed speaker or, if the passed speaker is in a
        group, get the groups coordinators SoCo instance.

        :param models.speaker.Speaker speaker: Speaker whos instance / coordinators instance should be returned
        :returns: SoCo instance or coordinators SoCo instance
        :rtype: soco.Soco
        """
        soco_instance = soco.SoCo(speaker.ip_address)
        if soco_instance.group is not None and soco_instance.group.coordinator is not None:
            soco_instance = soco_instance.group.coordinator
        return soco_instance
Exemple #26
0
def define_player(ip_address, name):
    """Returning a SoCo object of the chosen player"""
    player = None
    if ip_address:
        player = soco.SoCo(ip_address)
    if name:
        player = get_player_by_name(name)

    if player and GROUP:
        # Change player to be the coordinator of the group
        player = player.group.coordinator

    return player
def set_master(speaker):
    try:
        ip_address(speaker)
    except ValueError:
        pass
    else:
        return soco.SoCo(speaker)

    sps = get_sonos_players()
    if not sps:
        return None

    sp_names = {s.player_name:s for s in sps}
    return sp_names.get(speaker)
Exemple #28
0
def init(**kwargs):
    """ Initialize variables for the unittests that are only known at run time
    """
    global SOCO  # pylint: disable-msg=W0603
    SOCO = soco.SoCo(kwargs['ip'])

    if len(SOCO.get_queue()) == 0:
        raise SoCoUnitTestInitError('Unit tests on the SoCo class must be run '
                                    'with at least 1 item in the playlist')

    transport_info = SOCO.get_current_transport_info()
    if transport_info['current_transport_state'] != 'PLAYING':
        raise SoCoUnitTestInitError('Unit tests on the SoCo class must be run '
                                    'with the sonos unit playing')
Exemple #29
0
    def _stream_to_speaker(self, speaker_ip, episodes):
        """ Play or enqueue selected episodes """

        urls = [episode.url for episode in episodes if SONOS_CAN_PLAY(episode)]
        logger.info('Streaming to Sonos %s: %s'%(speaker_ip, ', '.join(urls)))

        controller = soco.SoCo(speaker_ip)

        # enqueue and play
        for episode in episodes:
            controller.add_to_queue(episode.url)
            episode.playback_mark()

        controller.play()
Exemple #30
0
    def run(self):
        if not self.player:
            if self.ip:
                self.player = soco.SoCo(self.ip)
            elif self.name:
                self.player = soco.discovery.by_name(self.name)
            else:
                self.player = soco.discovery.any_soco()

        if not self.player:
            self.output = self.output_no_connection
            return

        try:
            track_info = self.group_coordinator.get_current_track_info()
            transp_info = self.group_coordinator.get_current_transport_info()
            player_name = self.player.player_name
            muted = self.player.mute
            volume = self.player.volume
        except:
            self.output = self.output_no_connection
            return

        state = transp_info["current_transport_state"]

        cdict = {
            "player_name": player_name,
            "volume": volume,
            "muted": "M" if muted else "",
            "title": track_info["title"],
            "artist": track_info["artist"],
            "album": track_info["album"],
            "duration": track_info["duration"][2:],
            "position": track_info["position"][2:],
            "state": self.state_text_map[state],
        }

        self.data = cdict

        if self.format_no_music is not None and state == "STOPPED":
            self.output = {
                "full_text": self.format_no_music.format(**cdict),
                "color": self.color_no_music
            }
        else:
            self.output = {
                "full_text": self.format.format(**cdict),
                "color": self.color
            }