def playTheme(data, cur, themes, sonosPlayer): if data['hw'] in themes.keys() and getLastAction(data, cur) == 'remove': from soco import SoCo sonos = SoCo(sonosPlayer) if sonos.get_current_transport_info() == 'PLAYING': return ''; sonos.unjoin(); sonos.play_uri(themes[data['hw']]) sonos.volume = 20; if sonos.get_current_transport_info() == 'PLAYING': return ''; sonos.play() syslog.syslog('Playing theme for: ' + data['hw'])
def now_playing(self): my_zone = SoCo('192.168.86.225') status = my_zone.get_current_transport_info() track = my_zone.get_current_track_info() artist = '' title = '' if(track['artist'] == '' and track['title'] == ''): return "Stopped - Playlist Empty" elif (track['artist'] == '' and track['title'] != ''): title = track['title'] parts = title.split('|') for part in parts: if(part[:7] == 'ARTIST '): artist = part[7:] elif(part[:6] == 'TITLE '): title = part[6:] else: artist = track['artist'] title = track['title'] state = "Now Playing: " if(status['current_transport_state'] == 'STOPPED'): state = "Up Next" return state + artist + ' - ' + title
class Sonos(AbstractJob): def __init__(self, conf): self.interval = conf['interval'] self.sonos = SoCo(conf['ip']) def get(self): zone_name = self.sonos.get_speaker_info()['zone_name'] np = self.sonos.get_current_track_info() current_track = np if np['playlist_position'] != '0' else None queue = self.sonos.get_queue(int(np['playlist_position']), 1) next_item = queue.pop() if len(queue) > 0 else None next_track = {} if next_item is not None: next_track = { 'artist': next_item.creator, 'title': next_item.title, 'album': next_item.album } state = self.sonos.get_current_transport_info()[ 'current_transport_state'] return { 'room': zone_name, 'state': state, 'current': current_track, 'next': next_track }
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 sexy_time(): # connect to the Sonos sonos = SoCo(SONOS_IP) # connect to Philips Hue Bridge hue = Bridge(ip=HUE_IP, username=HUE_USERNAME) # get queue queue = sonos.get_queue() # if we: # * already have a queue # * music is playing # * we are already playing a queue that begins with "Let's Get It On" # ...then skip to the next track if len(queue) > 0 and \ sonos.get_current_transport_info()['current_transport_state'] == "PLAYING" and \ queue[0].title == SEXY_TIME_FIRST_TRACK: sonos.next() # else, intitiate a fresh Sexy Time else: # clear Sonos queue sonos.clear_queue() # turn off shuffle and repeat sonos.play_mode = 'NORMAL' # set volume sonos.volume = 45 # play Sexy Time playlist playlist = get_sonos_playlist(sonos, SEXY_TIME_PLAYLIST_NAME) if playlist: sonos.add_to_queue(playlist) sonos.play() # dim the lights (bri out of 254) over the pre-defined amount of time command = { 'transitiontime': (SEXY_TIME_DIMMER_SECONDS * 10), 'on': True, 'bri': SEXY_TIME_DIMMER_BRIGHTNESS } hue.set_light(1, command) return jsonify(status="success")
def say(text): ok, file_name = text2mp3(text, PATH, LANGUAGE) if ok: zp = SoCo(IP) cur_info = zp.get_current_track_info() state = zp.get_current_transport_info() zp.play_uri("http://{0}:5000/static/speech.mp3".format(LAN_IP)) if (state['current_transport_state'] == 'PLAYING'): audio = MP3("./static/speech.mp3") speech_info = zp.get_current_track_info() duration = speech_info['duration'] Timer(audio.info.length, resume_queue, (zp, cur_info)).start() return "OK!"
def __init__(self): _LOGGER.info("Sonos Data: initializing") ### Debug variables IP = "192.168.0.85" ### Get data from the SoCo Library loadSocoData = SoCo(IP) self._SoCoData = loadSocoData self._model_name = loadSocoData.get_speaker_info()['model_name'] self._player_name = loadSocoData.player_name ### Misc self._icon = None self._state = loadSocoData.get_current_transport_info( )['current_transport_state']
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 callback(d): data = json.loads(d) url = data['url'] sonos_devices = SonosDiscovery() ips = sonos_devices.get_speaker_ips() master = SoCo(ips[0]) masteruid = master.get_speaker_info()['uid'] for ip in ips: if not (ip == master.speaker_ip): slave = SoCo(ip) ret = slave.join(masteruid) oldvol = master.volume master.volume = 60 master.play_uri(url) playing = True while playing: if master.get_current_transport_info()['current_transport_state'] == 'STOPPED': playing = False master.volume = oldvol for ip in ips: if not (ip == master.speaker_ip): slave = SoCo(ip) slave.unjoin()
def party(): # connect to the Sonos sonos = SoCo(SONOS_IP) # get queue queue = sonos.get_queue() # if we: # * already have a queue # * music is playing # ...then skip to the next track if len(queue) > 0 and sonos.get_current_transport_info()['current_transport_state'] == "PLAYING": sonos.next() # else, intitiate a fresh Party Time else: # clear Sonos queue sonos.clear_queue() # turn on shuffle, turn off repeat sonos.play_mode = 'SHUFFLE_NOREPEAT' # set volume sonos.volume = 45 # play Party playlist playlist = get_sonos_playlist(sonos, PARTY_TIME_PLAYLIST_NAME) if playlist: sonos.add_to_queue(playlist) sonos.play() return jsonify(status="success")
def isPlaying(player: SoCo) -> bool: return player.get_current_transport_info()['current_transport_state'] == 'PLAYING' or \ player.get_current_transport_info()['current_transport_state'] == 'TRANSITIONING'
def time(input): split_time = input.split(":") minutes = int(split_time[0]) * 60 seconds = int(split_time[1]) return minutes + seconds if __name__ == '__main__': nothing = "not_playing::::::::::::::" sonos = SoCo(ip) # Pass in the IP of your Sonos speaker track = sonos.get_current_track_info() state = sonos.get_current_transport_info() play_state = state['current_transport_state'] if track[ 'position'] == "NOT_IMPLEMENTED" or play_state == "STOPPED" or play_state == "PAUSED_PLAYBACK": print(nothing) else: artist = track['artist'] name = track['title'] album = track['album'] position = track['position'][2:] duration = track['duration'][2:] album_art = track['album_art'] position = str(time(position)) duration = str(time(duration))
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 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()
elif "p3star" in track['uri']: if not track['artist']: print "Content-type: text/html\n\n<img src=img/p3star.png style=width:48px;height:34px;> " else: print "Content-type: text/html\n\n<img src=img/p3star.png style=width:48px;height:34px;> " + track[ 'artist'] + " <br /> " + track['title'] elif "p4" in track['uri']: if not track['artist']: print "Content-type: text/html\n\n<img src=img/p4.png style=width:48px;height:34px;> " else: print "Content-type: text/html\n\n<img src=img/p4.png style=width:48px;height:34px;> " + track[ 'artist'] + " <br /> " + track['title'] # Get speaker status office_state = office.get_current_transport_info() office_track = office.get_current_track_info() living_room_state = living_room.get_current_transport_info() living_room_track = living_room.get_current_track_info() # Check if and which speaker is playing if office_state['current_transport_state'] == "PLAYING" and office_track[ 'duration'] == "NOT_IMPLEMENTED": if not office_track['artist']: sonos = SoCo('192.168.1.72') state = sonos.get_current_transport_info() if state['current_transport_state'] == "PAUSED_PLAYBACK": print "Content-type: text/html\n\n" + "Not playing" elif state['current_transport_state'] == "STOPPED": print "Content-type: text/html\n\n" + "Not playing" else:
from soco import SoCo Sonos = SoCo("192.168.0.21") LastVolume = Sonos.volume LastState = Sonos.get_current_transport_info()["current_transport_state"] while True: CurrentVolume = Sonos.volume if CurrentVolume != LastVolume: print(CurrentVolume) LastVolume = CurrentVolume CurrentVolume = Sonos.volume CurrentState = Sonos.get_current_transport_info( )["current_transport_state"] if CurrentState != LastState: print("Change in state!") LastState = CurrentState
def play(): info = x.get_current_transport_info() if info['current_transport_state'] == 'PAUSED_PLAYBACK': x.play() def pause(): info = x.get_current_transport_info() if info['current_transport_state'] != 'PAUSED_PLAYBACK': x.pause() x = SoCo('192.168.0.110') # to play: print(x.player_name) print(x.play_mode) print(x.get_current_transport_info()) # print(MusicService.get_subscribed_services_names()) # print(MusicService.get_all_music_services_names()) # print(x.volume) play_favorite(x, 'Toddler Radio') # play_favorite(x, 'Choo Choo Soul') # play_favorite(x, 'Bob the Builder') # play_favorite(x, 'Bat out of Hell [Bonus Tracks]') # play_album(x, 'Frozen (Soundtrack)') # list_favorites(x)
#load settings f = open('config.txt', 'r') settings = json.load(f) f.close() zone = SoCo(settings['SONOS_IP_ADDRESS']) url = settings['POST_SONGS_URL'] currentTrackInfo = None needToQuit = False while not needToQuit: try: newTrackInfo = zone.get_current_track_info() ## only procede if the player is playing if zone.get_current_transport_info( )['current_transport_state'] == 'PLAYING': ## if the current track exists and is different from the last we found procede if (currentTrackInfo == None or newTrackInfo['title'] != currentTrackInfo['title']): ##printlog(unicode(newTrackInfo)) payload = { "SonosName": zone.player_name, "Title": unicode(newTrackInfo['title']), "Artist": unicode(newTrackInfo['artist']), "Album": unicode(newTrackInfo['album']), "AlbumArt": unicode(newTrackInfo['album_art']) } r = requests.post(url, json=payload)
needToQuit = False ##list all available hipchat rooms ##and connect to the one specified in config.txt for room in hipchat.rooms()['items']: printlog(room['name']) if(room['name'] == hipChatRoomName): hipChatRoom = room printlog('joined room: ' + hipChatRoom['name']) while not needToQuit: try: newTrackInfo = zone.get_current_track_info() ## only procede if the player is playing if zone.get_current_transport_info()['current_transport_state'] == 'PLAYING': ## if the current track exists and is different from the last we found procede if(currentTrackInfo == None or newTrackInfo['title'] != currentTrackInfo['title']): #format a cool hipchat message containing a search link an album image and the track info #put together a google search url searchStr = unicode(newTrackInfo['title']) +' ' + unicode(newTrackInfo['artist']) + ' ' +unicode(newTrackInfo['album']) searchStr = searchStr.replace(' ','+') printlog(searchStr) noteStr = '<a href="http://www.google.com/search?q='+searchStr + '">' #only include the album image if this track has a different album from the last one if(currentTrackInfo == None or newTrackInfo['album'] != currentTrackInfo['album']): noteStr += '<img style="float:left; width:50px;height:50px;" src="' + unicode(newTrackInfo['album_art'])+ '">' noteStr += '<p >' noteStr += '<b>' + unicode(newTrackInfo['title']) + '</b>' noteStr += ' - <b>' + unicode(newTrackInfo['artist'])+ '</b>'
sys.exit() # init sonos directory_path = os.path.expanduser(dropbox_path) sonos = SoCo(sonos_ip) sonos.volume = sonos_volume state = '' # check if we should stop the plaver if argument == '-s': sonos.stop(); sys.exit() # enter main loop while True: state = sonos.get_current_transport_info()['current_transport_state'] if state == 'PLAYING': print 'Playing song. Waiting for it to finish...' else: print 'checking for files...' # get files from directory file_list = [f for f in listdir(directory_path) if isfile(join(directory_path, f))] # pick the first file that starts with file_prefix song_id = "" if len(file_list) > 0: for file in file_list: if file.startswith(file_prefix): full_filepath = directory_path + '/' + file
sys.path.append('../lib') from soco import SoCo from soco.exceptions import SoCoUPnPException if len(sys.argv) > 1: 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)
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()