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()
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()
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()
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()
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'
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
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()
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"
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()
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()
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
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()
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)
def stop(): target = request.args.get('target') sonos = SoCo(target) sonos.pause() return 'Ok'
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.
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
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()
def pause(self): for ip in self._ZONE_IPS: device = SoCo(ip) device.pause() return True
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()
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)
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()
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"
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
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