Пример #1
0
class Sonos:
	def __init__(self, ip):
		self.sonos = SoCo(ip)
		self.sonos.volume = 60

	def playJason(self):
		self.sonos.play_uri("x-sonos-spotify:spotify%3atrack%3a6g6A7qNhTfUgOSH7ROOxTD?sid=12&flags=32")
		time.sleep(1)
		self.sonos.pause()

	def randomKatyPerrySong(self):
		darkHorse = 'x-sonos-spotify:spotify%3atrack%3a5jrdCoLpJSvHHorevXBATy?sid=12&flags=32'
		firework = 'x-sonos-spotify:spotify%3atrack%3a4lCv7b86sLynZbXhfScfm2?sid=12&flags=32'
		roar = 'x-sonos-spotify:spotify%3atrack%3a3XSczvk4MRteOw4Yx3lqMU?sid=12&flags=32'
		birthday = 'x-sonos-spotify:spotify%3atrack%3a2xLOMHjkOK8nzxJ4r6yOKR?sid=12&flags=32'
		californiaGurls = 'x-sonos-spotify:spotify%3atrack%3a6tS3XVuOyu10897O3ae7bi?sid=12&flags=32'
		teenageDream = 'x-sonos-spotify:spotify%3atrack%3a55qBw1900pZKfXJ6Q9A2Lc?sid=12&flags=32'
		lastFridayNight	= 'x-sonos-spotify:spotify%3atrack%3a455AfCsOhhLPRc68sE01D8?sid=12&flags=32'
		peacock = 'x-sonos-spotify:spotify%3atrack%3a3y3Hucw52QpjtHUeOKTkaO?sid=12&flags=32'
		et = 'x-sonos-spotify:spotify%3atrack%3a4kkeuVl6gF3RMqE4Nn5W3E?sid=12&flags=32'

		songs = [darkHorse, firework, roar, birthday, californiaGurls, teenageDream, lastFridayNight, peacock, et]
		chosen_song = random.choice(songs)
		return chosen_song

	def playKatyPerry(self):
		self.playJason()
		self.sonos.play_uri(self.randomKatyPerrySong())
		# set Katy Perry duration here (in seconds)
		time.sleep(10)
		self.sonos.pause()
Пример #2
0
    def do(self, params):
        speaker = SoCo(socket.gethostbyname(params['host']))
        print(speaker.groups)

        if 'volume' in params:
            speaker.volume = params['volume']

        if 'clear_queue' in params:
            speaker.clear_queue()

        if 'add_playlist_id_to_queue' in params:
            playlist = speaker.get_sonos_playlists()[
                params['add_playlist_id_to_queue']]
            speaker.add_uri_to_queue(playlist.resources[0].uri)

        if 'switch_to_tv' in params:
            speaker.switch_to_tv()

        if 'next' in params:
            speaker.next()
        elif 'previous' in params:
            speaker.previous()

        if 'play' in params:
            speaker.play()
        elif 'pause' in params:
            speaker.pause()

        if 'set_sleep_timer' in params:
            speaker.set_sleep_timer(params['set_sleep_timer'] * 60)
class CommonHardwareSoco(object):
    """
    Class for Sonos
    """

    def __init__(self, ip_addr):
        self.soco_inst = SoCo(ip_addr)

    def com_hardware_soco_name(self):
        return self.soco_inst.player_name

    def com_hardware_soco_volume(self, set_volume):
        self.soco_inst.volume = set_volume

    def com_hardware_soco_light_status(self, light_status):
        self.soco_inst.status_light = light_status

    def com_hardware_soco_play_url(self, url):
        self.soco_inst.play_uri(url)

    def com_hardware_soco_pause(self):
        self.soco_inst.pause()

    def com_hardware_soco_play(self):
        # Play a stopped or paused track
        self.soco_inst.play()
Пример #4
0
	def playpause(self):
		my_zone = SoCo('192.168.1.19')
		status = my_zone.get_current_transport_info()
		if(status['current_transport_state'] == "PLAYING"):
			print('Sonos - Pause')
			my_zone.pause()
		else:
			print('Sonos- Play')
			my_zone.play()
Пример #5
0
 def action(player: SoCo, action: str):
     if action == 'play':
         player.play()
     elif action == 'stop':
         player.stop()
     elif action == 'pause':
         player.pause()
     elif action == 'next':
         player.next()
     elif action == 'previous':
         player.previous()
Пример #6
0
def tune():
    station = request.args.get('station')
    target = request.args.get('target')
    sonos = SoCo(target)
    sonos.pause()
    if station == 'eldoradio':
        sonos.play_uri('x-rincon-mp3radio://sender.eldoradio.de:8000/high')
    elif station == 'xfm':
        sonos.play_uri('x-rincon-mp3radio://live64.917xfm.de')
    elif station == 'wdr5':
        sonos.play_uri('x-rincon-mp3radio://wdr-5.akacast.akamaistream.net/7/41/119439/v1/gnl.akacast.akamaistream.net/wdr-5')
    return 'Ok'
Пример #7
0
    def sonos_pause(self):
        """Afspeellijst, <pause> button, afspelen pauzeren.
        """
        
        # pagina laden voor als antwoord terug aan de server
        h = queuebeheer_temp.sonos_pause()
                
        ## sonos, afspelen pauzeren
        sonos = SoCo(COORDINATOR)
        sonos.pause()

        return h
Пример #8
0
class SonoController():
    def __init__(self, ip):
        self.core = SoCo(ip)

    def play_uri(self, url):
        self.core.play_uri(url)

    def play_by_userName(self, name):
        url = URL_BASE.get(name, "Unknown")
        if (url == "Unknown"):
            track = self.core.get_current_track_info()
            current_play = track['title']
            # print track['title']
            target_play = MUSIC_BASE.get(url, "Unknow")
            # print target_play
            if (current_play == target_play):
                print "unknown person"
            else:
                self.core.clear_queue()
                self.core.add_uri_to_queue(ALARM_URL)
                self.core.add_uri_to_queue(END_URL)
                self.core.play_from_queue(0, True)
        else:
            track = self.core.get_current_track_info()
            current_play = track['title']
            # print track['title']
            target_play = MUSIC_BASE.get(url, "Unknow")
            # print target_play
            if (current_play == target_play):
                print "the same person"
            else:
                self.core.clear_queue()
                self.core.add_uri_to_queue(url)
                self.core.add_uri_to_queue(END_URL)
                self.core.play_from_queue(0, True)

    def pause(self):
        self.core.pause()

    def mute(self):
        self.core.mute = True

    def unMute(self):
        self.core.mute = False

    def setVolume(self, val):
        self.core.volume = val

    def alarm(self):
        self.play_uri(ALARM_URL)
        time.sleep(8.0)
        self.pause()
Пример #9
0
def sonos(command, volume=-1):
    s = SoCo(app.config['SONOS'])
    try:
        if command == 'play':
            s.play()
        elif command == 'pause':
            s.pause()
        elif command =='volume':
            logging.info('Setting volume of Sonos to %d' % volume)
            s.volume(volume)
        elif command == 'next':
            s.next()
        elif command == 'previous':
            s.previous()
        return "OK"
    except:
        return "FAIL"
Пример #10
0
def play(device, queueable_item):
    sonos = SoCo(device)
    track = sonos.get_current_track_info()
    initial_playlist_position = int(track["playlist_position"]) - 1

    initial_track_position = (track["position"])
    initial_state = sonos.get_current_transport_info().get(
        "current_transport_state")
    initial_volume = sonos.volume
    sonos.volume = 3
    sonos.play_uri(uri=queueable_item, meta='')
    time.sleep(2)
    sonos.volume = initial_volume
    sonos.play_from_queue(initial_playlist_position)
    sonos.seek(initial_track_position)
    if initial_state != 'PLAYING':
        sonos.pause()
Пример #11
0
def playTrack(mp3, location):

    my_sonos = '192.168.0.43'
    enemy_sonos = '192.168.0.43'

    if location == "self":
        ip = my_sonos
    else:
        ip = enemy_sonos

    sonos = SoCo(ip)  # Sonos

    sonos.play_uri(mp3)
    track = sonos.get_current_track_info()
    print track['title']
    sonos.pause()
    sonos.play()
Пример #12
0
 def pause(self):
     self.logger.info('Pausing zones...')
     for ip in self._ZONE_IPS:
         device = SoCo(ip)
         self.logger.debug('Pausing zone at %s', ip)
         if not device.pause():
             self.logger.error('Unable to pause zone at %s', ip)
             return False
     self.logger.info('All zones paused.')
     return True
Пример #13
0
    def pause(self):
        self.logger.info('Pausing zones...')
        for ip in self._ZONE_IPS:
            device = SoCo(ip)
            self.logger.debug('Pausing zone at %s', ip)
	    if not device.pause():
                self.logger.error('Unable to pause zone at %s', ip)
		return False
	self.logger.info('All zones paused.')
        return True
Пример #14
0
def playTrack( mp3, location ):


        my_sonos     = ['192.168.0.135']
        enemy_sonos  = ['192.168.0.144','192.168.0.135'] #testing with 2 sonos only
        #enemy_sonos  = ['192.168.0.12','192.168.0.15'] #multiple enemies
       # enemy_sonos  = '192.168.0.15' #single enemy

        ips = []
        if location == "self":
               ips = my_sonos
        else:
               ips = enemy_sonos

        for ip in ips:
            sonos = SoCo( ip ) # Sonos
            sonos.play_uri( mp3 )
            track = sonos.get_current_track_info()
            print track['title']
            sonos.pause()
            sonos.play()
Пример #15
0
def interaction_manager(speaker_ip: str) -> None:
    sys.stdin = open(0)
    speaker = SoCo(speaker_ip)
    while True:
        try:
            # keypress = wait_for_keypress()
            keypress = input("")[0]
        except:
            keypress = ""
        if keypress in ["N", "n"]:
            action = "NEXT"
            print("Next track ...")
            speaker.stop()
            logging.info("Interactive mode: key = '{}', action = '{}'".format(
                keypress, action))
        if keypress in ["P", "p"]:
            action = "PAUSE"
            print("Pause playback ...")
            try:
                speaker.pause()
            except Exception as e:
                logging.info("Exception ignored: {}".format(e))
            logging.info("Interactive mode: key = '{}', action = '{}'".format(
                keypress, action))
        if keypress in ["R", "r"]:
            action = "RESUME"
            print("Resume playback ...")
            try:
                speaker.play()
            except Exception as e:
                logging.info("Exception ignored: {}".format(e))
            logging.info("Interactive mode: key = '{}', action = '{}'".format(
                keypress, action))
        # Windows captures CTRL-C key-presses, so we handle them directly here
        if name == "nt" and keypress == "\x03":
            logging.info(
                "Windows CTRL-C: Stopping speaker '{}' and exiting".format(
                    speaker.player_name))
            speaker.stop()
            os._exit(0)
Пример #16
0
def stop():
    target = request.args.get('target')
    sonos = SoCo(target)
    sonos.pause()    
    return 'Ok'
Пример #17
0
from soco import SoCo
import time
Sonos = SoCo("192.168.0.21")
#IP Adress of the desired speaker.
while True:
    CurrentState = Sonos.get_current_transport_info(
    )["current_transport_state"]
    if CurrentState == "PAUSED_PLAYBACK":
        time.sleep(300)
        #Time before the status is checked again.
        CurrentState = Sonos.get_current_transport_info(
        )["current_transport_state"]
        if CurrentState == "PAUSED_PLAYBACK":
            Sonos.play_uri(
                "x-rincon-mp3radio://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio2_mf_q?s=1527663981&e=1527678381&h=dc603413da37642fe5f6914969d4c548",
                title="Radio 2")
            #URI for radio stream. Replace http with x-rincon-mp3radio:// The title tag can be changed to suit the radio station.
            Sonos.pause()
            #Pauses the audio before it can start playing.
    time.sleep(300)
    #Time before status is checked again.
Пример #18
0
class SonosController:

    _device = None

    def connect(self):
        ips = []
        while (len(ips) == 0):
            print "No Sonos found"
            sonos_devices = SonosDiscovery()
            ips = sonos_devices.get_speaker_ips()

        print "Found {0} device(s)".format(len(ips))

        for ip in ips:
            self._device = SoCo(ip)
            zone_name = self._device.get_speaker_info()['zone_name']
            print "IP of {0} is {1}".format(zone_name, ip)

    def get_current_song(self):
        if self._device == None:
            self.connect()

        now_playing = self._device.get_current_track_info()
        return now_playing

    def play_pandora_station(self, code):
        if self._device == None:
            self.connect()

        PLAY_STATION_ACTION = '"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"'
        TRANSPORT_ENDPOINT = '/MediaRenderer/AVTransport/Control'
        JOIN_RESPONSE = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURIResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"></u:SetAVTransportURIResponse></s:Body></s:Envelope>'
        PLAY_STATION_BODY_TEMPLATE = '"<u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>pndrradio:{music_service_station_id}</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>'

        body = PLAY_STATION_BODY_TEMPLATE.format(music_service_station_id=code)
        response = self._device.send_command(TRANSPORT_ENDPOINT,
                                             PLAY_STATION_ACTION, body)

        if (response == JOIN_RESPONSE):
            self._device.play()
            return True
        else:
            return self._device.parse_error(response)

    def pause(self):
        if self._device == None:
            connect()

        try:
            self._device.pause()
        except:
            print "Error trying to pause music: there is probably nothing playing right now."
            return False

        return True

    def get_volume(self):
        if self._device == None:
            self.connect()

        current_volume = self._device.volume()
        return current_volume

    def set_volume(self, volume):
        if self._device == None:
            self.connect()

        result = self._device.volume(volume)
        return result
Пример #19
0
from soco import SoCo

if __name__ == '__main__':
    sonos = SoCo('192.168.178.37') # Pass in the IP of your Sonos speaker
    # You could use the discover function instead, if you don't know the IP

    # Pass in a URI to a media file to have it streamed through the Sonos
    # speaker
    sonos.play_uri(
        'x-rincon-mp3radio://sender.eldoradio.de:8000/high')

    track = sonos.get_current_track_info()

    print track['title']

    sonos.pause()

    # Play a stopped or paused track
    sonos.play()
Пример #20
0
 def pause(self):
     for ip in self._ZONE_IPS:
         device = SoCo(ip)
         device.pause()
     return True
Пример #21
0
class SonosStateMc:

    def __init__(self, sonos_ip):
        self.state_var = SONOS_IDLE
        self.sonos_ip = sonos_ip
        self.sonos = SoCo(self.sonos_ip)
        self.vol_to_return_to = self.sonos.volume
        self.time_out = 0
        self.retry_count = 0
        self.state_entry_time = time.time()
        self.prev_state = SONOS_IDLE
        self.logged_idle = False
        self.sound_uri = ""
        self.play_pending = False
        self.abort_pending = False
        self.play_volume = 30
        self.track_info_to_return_to = None
        self.state_info_to_return_to = None

    def execCmd(self, cmd, param, meta):
        self.state_var = SONOS_IDLE
        self.play_pending = False
        self.abort_pending = False
        if cmd.lower() == "play":
            if param == "":
                self.sonos.play()
            else:
                self.sonos.play_uri(param, meta)
        elif cmd.lower() == "stop":
            self.sonos.stop()
        elif cmd.lower() == "volup":
            self.sonos.volume = self.sonos.volume + 10
        elif cmd.lower() == "voldown":
            self.sonos.volume = self.sonos.volume - 10

    def musicStop(self):
        self.state_var = SONOS_IDLE
        self.play_pending = False
        self.abort_pending = False
        self.sonos.stop()

    def getDeviceName(self):
        return self.sonos.player_name

    def getFavouriteRadioStations(self):
        return self.sonos.get_favorite_radio_stations(0,6)

    def playSound(self, soundUri, playVolume):
        self.sound_uri = soundUri
        self.play_volume = playVolume
        self.play_pending = True

    def elapsedTime(self):
        return time.time() - self.state_entry_time

    def changeState(self, newState):
        self.prev_state = self.state_var
        self.state_var = newState
        self.state_entry_time = time.time()

    def restore(self):
        self.sonos.volume = self.vol_to_return_to
        # Check for radio or similar
        # Currently this is done by checking the track duration
        if self.track_info_to_return_to["duration"] == "0:00:00":
            # Handle playing from the radio or similar
            self.sonos.play_uri(self.track_info_to_return_to["uri"])
        else:
            # Handle continuation of playing a track from the queue
            try:
                queue_pos = int(self.track_info_to_return_to["playlist_position"]) - 1
            except:
                return
            self.sonos.play_from_queue(queue_pos)
            self.sonos.seek(self.track_info_to_return_to["position"])
        if self.state_info_to_return_to["current_transport_state"] == "PAUSED_PLAYBACK" or self.state_info_to_return_to["current_transport_state"] == "STOPPED":
            self.changeState(SONOS_RESTORE_PEND)
            self.time_out = 3
            self.retry_count = 2
        else:
            self.completed()

    def abort(self):
        self.logState("Aborting")
        self.play_pending = False
        self.abort_pending = True
        self.restore()

    def completed(self):
        if self.abort_pending:
            self.logState("Finished - ABORTED")
        else:
            self.logState("Finished - OK")
        self.play_pending = False
        self.abort_pending = False
        self.changeState(SONOS_IDLE)

    def logState(self, info):
        if self.state_var == SONOS_IDLE:
            if self.logged_idle:
                return
            self.logged_idle = True
        else:
            self.logged_idle = False
        transp_info = self.sonos.get_current_transport_info()
        track_info = self.sonos.get_current_track_info()
        print ("StateNow: ", self.state_var, " PrevState", self.prev_state, " TimeOut: ", self.time_out, " Elapsed: ", self.elapsedTime(), "RetryCount: ", self.retry_count, " TranspState: ", transp_info["current_transport_state"], " PlaylistPos: ", track_info["playlist_position"], "Info: ", info)

    def handleState(self):
        # Handle idle
        if self.state_var == SONOS_IDLE:
            if self.play_pending:
                self.changeState(SONOS_PLAY_REQ)
            return
        # Get current state information from sonos unit
        transp_info = self.sonos.get_current_transport_info()
        track_info = self.sonos.get_current_track_info()
        cur_transp_state = transp_info['current_transport_state']
        self.logState("handleStateEntry")
        # Handle other states
        if self.state_var == SONOS_PLAY_REQ:
            self.vol_to_return_to = self.sonos.volume
            self.track_info_to_return_to = track_info
            self.state_info_to_return_to = transp_info
            self.retry_count = 2
            self.changeState(SONOS_PAUSE_TRY)
        elif self.state_var == SONOS_PAUSE_TRY:
            self.time_out = 10
            if cur_transp_state == "PLAYING":
                self.sonos.pause()
            self.changeState(SONOS_PAUSE_PEND)
        elif self.state_var == SONOS_PAUSE_PEND:
            if cur_transp_state == "PAUSED_PLAYBACK" or cur_transp_state == "STOPPED":
                self.changeState(SONOS_PLAY_START)
            elif cur_transp_state == "PLAYING":
                if self.elapsedTime() > self.time_out:
                    self.retry_count -= 1
                    if self.retry_count > 0:
                        self.changeState(SONOS_PAUSE_TRY)
                    else:
                        self.logState("FAILED TO PAUSE - STILL PLAYING")
                        self.abort()
            else:
                self.logState("FAILED TO PAUSE - UNKNOWN STATE")
                self.abort()
        elif self.state_var == SONOS_PLAY_START:
            self.sonos.volume = self.play_volume
            self.sonos.play_uri(self.sound_uri)
            self.time_out = 30
            self.retry_count = 2
            self.changeState(SONOS_PLAY_PEND)
        elif self.state_var == SONOS_PLAY_PEND:
            if cur_transp_state == "PLAYING":
                self.changeState(SONOS_PLAYING)
            else:
                if self.elapsedTime() > self.time_out:
                    self.retry_count -= 1
                    if self.retry_count > 0:
                        self.changeState(SONOS_PLAY_START)
                    else:
                        self.logState("FAILED TO PLAY")
                        self.abort()
        elif self.state_var == SONOS_PLAYING:
            if cur_transp_state == "PLAYING":
                if self.elapsedTime() > self.time_out:
                    self.logState("FAILED TO FINISH PLAYING BEFORE TIMEOUT - TRACK TOO LONG?")
                    self.abort()
            else:
                self.restore()
        elif self.state_var == SONOS_RESTORE_PEND:
            if cur_transp_state == "PLAYING":
                if self.state_info_to_return_to["current_transport_state"] == "PAUSED_PLAYBACK":
                    self.sonos.pause()
                elif self.state_info_to_return_to["current_transport_state"] == "STOPPED":
                    self.sonos.stop()
                self.completed()
            else:
                if self.elapsedTime() > self.time_out:
                    self.logState("FAILED TO RESTORE")
                    self.completed()
Пример #22
0
class Component(ThreadComponent):
    MATRIX = matrices.MUSIC_NOTE

    STATE_PLAYING = 'PLAYING'
    STATE_PAUSED = 'PAUSED_PLAYBACK'
    STATE_STOPPED = 'STOPPED'

    # how many seconds to wait after sending last command before
    # receiving device state change events
    EVENT_IDLE_INTERVAL = 2  # seconds

    def __init__(self, component_config):
        super().__init__(component_config)

        self.sonos_controller = SoCo(component_config['ip_address'])
        self.volume_range = range(0, 100)
        self.event_listener = event_listener  # comes from global scope
        self.state = None
        self.volume = None
        self.nuimo = None
        self.last_request_time = time()

        self.sonos_joined_controllers = []

        self.station_id_1 = component_config.get('station1', None)
        self.station_id_2 = component_config.get('station2', None)
        self.station_id_3 = component_config.get('station3', None)

        if not any((self.station_id_1, self.station_id_2, self.station_id_3)):
            try:
                favorites = self.sonos_controller.get_sonos_favorites(
                    max_items=3)
            except SoCoException:
                self.nuimo.display_matrix(matrices.ERROR)
            if favorites['returned'] >= 3:
                self.station_id_1 = favorites['favorites'][0]
                self.station_id_2 = favorites['favorites'][1]
                self.station_id_3 = favorites['favorites'][2]

        if len(
                self.sonos_controller.group.members
        ) > 1 and self.sonos_controller.group.coordinator.ip_address == component_config[
                'ip_address']:
            for sonos_controller in self.sonos_controller.group.members:
                if sonos_controller.ip_address != component_config[
                        'ip_address'] and sonos_controller.player_name != self.sonos_controller.group.coordinator.player_name:
                    self.sonos_joined_controllers.append(
                        SoCo(sonos_controller.ip_address))

    def run(self):
        self.subscribe_to_events()
        self.update_state()
        try:
            self.run_loop()
        finally:
            self.unsubscribe_from_events()

    def run_loop(self):
        while not self.stopped:
            try:
                event = self.av_transport_subscription.events.get(timeout=0.1)

                if time() - self.last_request_time > self.EVENT_IDLE_INTERVAL:
                    logger.debug("avTransport event: %s",
                                 pformat(event.variables))
                    self.state = event.variables['transport_state']
            except Empty:
                pass

            try:
                event = self.rendering_control_subscription.events.get(
                    timeout=0.1)

                if time() - self.last_request_time > self.EVENT_IDLE_INTERVAL:
                    logger.debug("renderingControl event: %s",
                                 pformat(event.variables))
                    self.volume = int(event.variables['volume']['Master'])
            except Empty:
                pass

    def subscribe_to_events(self):
        self.av_transport_subscription = self.sonos_controller.avTransport.subscribe(
        )
        self.rendering_control_subscription = self.sonos_controller.renderingControl.subscribe(
        )

    def unsubscribe_from_events(self):
        self.rendering_control_subscription.unsubscribe()
        self.av_transport_subscription.unsubscribe()

    def update_state(self):
        self.state = self.sonos_controller.get_current_transport_info(
        )['current_transport_state']
        self.volume = self.sonos_controller.volume

        logger.debug("%s state: %s volume: %s",
                     self.sonos_controller.ip_address, self.state, self.volume)

    def on_rotation(self, delta):
        if self.state is not None:
            try:
                delta = round(self.volume_range.stop * delta)
                self.volume = clamp_value(self.volume + delta,
                                          self.volume_range)
                self.sonos_controller.volume = self.volume
                if self.sonos_joined_controllers != []:
                    for sonos_joined_controller in self.sonos_joined_controllers:
                        sonos_joined_controller.volume = self.volume

                logger.debug("volume update delta: %s volume: %s", delta,
                             self.volume)

                matrix = matrices.progress_bar(self.volume /
                                               self.volume_range.stop)
                self.nuimo.display_matrix(matrix,
                                          fading=True,
                                          ignore_duplicates=True)
            except SoCoException:
                self.nuimo.display_matrix(matrices.ERROR)

            self.last_request_time = time()
        else:
            self.nuimo.display_matrix(matrices.ERROR)
            logger.debug("No Active connection with Host")

    def on_button_press(self):
        if self.state == self.STATE_PLAYING:
            self.pause()
            logger.debug("Play Paused by self.pause() on button press.")

        elif self.state in [self.STATE_PAUSED, self.STATE_STOPPED]:
            self.play()
            logger.debug(
                "Play started/resumed by self.pause() on button press.")

        elif self.state is None:
            self.nuimo.display_matrix(matrices.ERROR)
            logger.debug("No Active connection with Host.")

        logger.debug("state toggle: %s", self.state)

        self.last_request_time = time()

    def pause(self, show_matrix=True):
        try:
            self.sonos_controller.pause()
            self.state = self.STATE_PAUSED
            if show_matrix:
                self.nuimo.display_matrix(matrices.PAUSE)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

    def play(self, show_matrix=True):
        try:
            self.sonos_controller.play()
            self.state = self.STATE_PLAYING
            if show_matrix:
                self.nuimo.display_matrix(matrices.PLAY)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

    def on_swipe_right(self):
        try:
            self.sonos_controller.next()
            if self.state != self.STATE_PLAYING:
                self.play(show_matrix=False)
            self.nuimo.display_matrix(matrices.NEXT_SONG)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

        self.last_request_time = time()

    def on_swipe_left(self):
        try:
            self.sonos_controller.previous()
            if self.state != self.STATE_PLAYING:
                self.play(show_matrix=False)
            self.nuimo.display_matrix(matrices.PREVIOUS_SONG)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

        self.last_request_time = time()

    def on_longtouch_left(self):
        logger.debug("favorite left")
        if self.station_id_1 is not None:
            try:
                self.play_track_playlist_or_album(self.station_id_1,
                                                  matrices.STATION1)
            except SoCoException:
                self.nuimo.display_matrix(matrices.ERROR)

    def on_longtouch_bottom(self):
        logger.debug("favorite bottom")
        if self.station_id_2 is not None:
            try:
                self.play_track_playlist_or_album(self.station_id_2,
                                                  matrices.STATION2)
            except SoCoException:
                self.nuimo.display_matrix(matrices.ERROR)

    def on_longtouch_right(self):
        logger.debug("favorite right")
        if self.station_id_3 is not None:
            try:
                self.play_track_playlist_or_album(self.station_id_3,
                                                  matrices.STATION3)
            except SoCoException:
                self.nuimo.display_matrix(matrices.ERROR)

    def play_track_playlist_or_album(self, src, matrix):
        try:
            if 'object.container.playlistContainer' in src[
                    'meta'] or 'object.container.album.musicAlbum' in src[
                        'meta']:
                self._replace_queue_with_playlist(src)
                self.sonos_controller.play_from_queue(0)
            else:
                self.sonos_controller.play_uri(uri=src['uri'],
                                               meta=src['meta'],
                                               title=src['title'])
            self.nuimo.display_matrix(matrix)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

    def _replace_queue_with_playlist(self, src):
        """Replace queue with playlist represented by src.

        Playlists can't be played directly with the self.sonos_controller.play_uri
        API as they are actually composed of mulitple URLs. Until soco has
        suppport for playing a playlist, we'll need to parse the playlist item
        and replace the current queue in order to play it.
        """
        import soco
        import xml.etree.ElementTree as ET

        root = ET.fromstring(src['meta'])
        namespaces = {
            'item': 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/',
            'desc': 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/'
        }
        desc = root.find('item:item', namespaces).find('desc:desc',
                                                       namespaces).text

        res = [
            soco.data_structures.DidlResource(uri=src['uri'],
                                              protocol_info="DUMMY")
        ]
        didl = soco.data_structures.DidlItem(title="DUMMY",
                                             parent_id="DUMMY",
                                             item_id=src['uri'],
                                             desc=desc,
                                             resources=res)

        self.sonos_controller.stop()
        self.sonos_controller.clear_queue()
        self.sonos_controller.play_mode = 'NORMAL'
        self.sonos_controller.add_to_queue(didl)
Пример #23
0
class Component(ThreadComponent):
    MATRIX = matrices.MUSIC_NOTE

    STATE_PLAYING = 'PLAYING'
    STATE_PAUSED = 'PAUSED_PLAYBACK'
    STATE_STOPPED = 'STOPPED'

    # how many seconds to wait after sending last command before
    # receiving device state change events
    EVENT_IDLE_INTERVAL = 2  # seconds

    def __init__(self, component_config):
        super().__init__(component_config)

        self.sonos_controller = SoCo(component_config['ip_address'])
        self.volume_range = range(0, 100)
        self.event_listener = event_listener  # comes from global scope
        self.state = None
        self.volume = None
        self.nuimo = None
        self.last_request_time = time()

    def run(self):
        self.subscribe_to_events()
        self.update_state()
        try:
            self.run_loop()
        finally:
            self.unsubscribe_from_events()

    def run_loop(self):
        while not self.stopped:
            try:
                event = self.av_transport_subscription.events.get(timeout=0.1)

                if time() - self.last_request_time > self.EVENT_IDLE_INTERVAL:
                    logger.debug("avTransport event: %s",
                                 pformat(event.variables))
                    self.state = event.variables['transport_state']
            except Empty:
                pass

            try:
                event = self.rendering_control_subscription.events.get(
                    timeout=0.1)

                if time() - self.last_request_time > self.EVENT_IDLE_INTERVAL:
                    logger.debug("renderingControl event: %s",
                                 pformat(event.variables))
                    self.volume = int(event.variables['volume']['Master'])
            except Empty:
                pass

    def subscribe_to_events(self):
        self.av_transport_subscription = self.sonos_controller.avTransport.subscribe(
        )
        self.rendering_control_subscription = self.sonos_controller.renderingControl.subscribe(
        )

    def unsubscribe_from_events(self):
        self.rendering_control_subscription.unsubscribe()
        self.av_transport_subscription.unsubscribe()

    def update_state(self):
        self.state = self.sonos_controller.get_current_transport_info(
        )['current_transport_state']
        self.volume = self.sonos_controller.volume

        logger.debug("%s state: %s volume: %s",
                     self.sonos_controller.ip_address, self.state, self.volume)

    def on_rotation(self, delta):
        try:
            delta = round(self.volume_range.stop * delta)
            self.volume = clamp_value(self.volume + delta, self.volume_range)
            self.sonos_controller.volume = self.volume

            logger.debug("volume update delta: %s volume: %s", delta,
                         self.volume)

            matrix = matrices.progress_bar(self.volume /
                                           self.volume_range.stop)
            self.nuimo.display_matrix(matrix,
                                      fading=True,
                                      ignore_duplicates=True)

        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

        self.last_request_time = time()

    def on_button_press(self):
        if self.state == self.STATE_PLAYING:
            self.pause()

        elif self.state in [self.STATE_PAUSED, self.STATE_STOPPED]:
            self.play()

        logger.debug("state toggle: %s", self.state)

        self.last_request_time = time()

    def pause(self, show_matrix=True):
        try:
            self.sonos_controller.pause()
            self.state = self.STATE_PAUSED
            if show_matrix:
                self.nuimo.display_matrix(matrices.PAUSE)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

    def play(self, show_matrix=True):
        try:
            self.sonos_controller.play()
            self.state = self.STATE_PLAYING
            if show_matrix:
                self.nuimo.display_matrix(matrices.PLAY)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

    def on_swipe_right(self):
        try:
            self.sonos_controller.next()
            if self.state != self.STATE_PLAYING:
                self.play(show_matrix=False)
            self.nuimo.display_matrix(matrices.NEXT_SONG)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

        self.last_request_time = time()

    def on_swipe_left(self):
        try:
            self.sonos_controller.previous()
            if self.state != self.STATE_PLAYING:
                self.play(show_matrix=False)
            self.nuimo.display_matrix(matrices.PREVIOUS_SONG)
        except SoCoException:
            self.nuimo.display_matrix(matrices.ERROR)

        self.last_request_time = time()
Пример #24
0
if __name__ == '__main__':
    if (len(sys.argv) != 3):
        print "Usage: sonoshell.py [speaker's IP] [cmd]"
        print ""
        print "Valid commands: play, pause, stop, next, previous, current, and partymode"
        sys.exit()

    speaker_ip = sys.argv[1]
    cmd = sys.argv[2].lower()

    sonos = SoCo(speaker_ip)

    if (cmd == 'partymode'):
        print sonos.partymode()
    elif (cmd == 'play'):
        print sonos.play()
    elif (cmd == 'pause'):
        print sonos.pause()
    elif (cmd == 'stop'):
        print sonos.stop()
    elif (cmd == 'next'):
        print sonos.next()
    elif (cmd == 'previous'):
        print sonos.previous()
    elif (cmd == 'current'):
        track = sonos.get_current_track_info()

        print 'Current track: ' + track['artist'] + ' - ' + track['title'] + '. From album ' + track['album'] + '. This is track number ' + track['playlist_position'] + ' in the playlist. It is ' + track['duration'] + ' minutes long.'
    else:
        print "Valid commands: play, pause, stop, next, previous, current, and partymode"
Пример #25
0
class SonosController:

    _device = None

    def connect(self):
	ips = []
	while (len(ips) == 0):
	    print "No Sonos found"
	    sonos_devices = SonosDiscovery()
	    ips = sonos_devices.get_speaker_ips()
	
        print "Found {0} device(s)".format(len(ips))

	for ip in ips:
	    self._device = SoCo(ip)
	    zone_name = self._device.get_speaker_info()['zone_name']
	    print "IP of {0} is {1}".format(zone_name, ip)

    def get_current_song(self):
	if self._device == None:
	    self.connect()

	now_playing = self._device.get_current_track_info()
	return now_playing

    def play_pandora_station(self, code):
	if self._device == None:
	    self.connect()
	
	PLAY_STATION_ACTION ='"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"'
	TRANSPORT_ENDPOINT = '/MediaRenderer/AVTransport/Control'
	JOIN_RESPONSE = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURIResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"></u:SetAVTransportURIResponse></s:Body></s:Envelope>'
	PLAY_STATION_BODY_TEMPLATE ='"<u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>pndrradio:{music_service_station_id}</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>'
	
	body = PLAY_STATION_BODY_TEMPLATE.format(music_service_station_id = code)
	response = self._device.send_command(TRANSPORT_ENDPOINT, PLAY_STATION_ACTION, body)
	
	if (response == JOIN_RESPONSE):
	    self._device.play()
	    return True
	else:
	    return self._device.parse_error(response)

    def pause(self):
	if self._device == None:
	    connect()

	try:
	    self._device.pause()
	except:
            print "Error trying to pause music: there is probably nothing playing right now."
	    return False
	
	return True

    def get_volume(self):
        if self._device == None:
            self.connect()

        current_volume = self._device.volume()
        return current_volume

    def set_volume(self, volume):
        if self._device == None:
            self.connect()

        result = self._device.volume(volume)
        return result
Пример #26
0
    action_payload = json.loads(sys.argv[1])

    action = action_payload['action_argument']
    sonos_zone = action_payload['action_zone']

    sonos = SoCo(sonos_zone)

    if action == 'pp':
        # Play / Paused based on current playback state
        try:
            playback_state = sonos.get_current_transport_info(
            )['current_transport_state']
            if playback_state == 'STOPPED':
                sonos.play()
            elif playback_state == 'PLAYING':
                sonos.pause()
        except SoCoUPnPException as e:
            print '[{"icon": "font-awesome:times-circle", "title": "Not supported by current zone."}]'

    elif action == 'v+5':
        # Increase volume
        current_vol = sonos.volume
        new_vol = current_vol + 5
        if new_vol > 100:
            new_vol = 100
        sonos.ramp_to_volume(new_vol)

    elif action == 'v-5':
        # Decrease volume
        current_vol = sonos.volume
        new_vol = current_vol - 5
Пример #27
0
 def pause(self):
     for ip in self._ZONE_IPS:
         device = SoCo(ip)
         device.pause()
     return True