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 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 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 GET(self, ipadress): web.header('Content-Type', 'application/json') web.header('Access-Control-Allow-Origin', '*') web.header('Access-Control-Allow-Credentials', 'true') sonos = SoCo(ipadress) track = sonos.get_current_track_info() return json.dumps(track)
def GET(self): web.header('Access-Control-Allow-Origin', '*') web.header('Access-Control-Allow-Credentials', 'true') data = web.input(uri="no", player="no") sonos = SoCo('192.168.1.105') sonos.play_uri(data.uri) track = sonos.get_current_track_info() return track['title'] + " - " + data.player
def GET(self): web.header('Content-Type', 'application/json') web.header('Access-Control-Allow-Origin', '*') web.header('Access-Control-Allow-Credentials', 'true') data = web.input(player="blank") sonos = SoCo(data.player) track = sonos.get_current_track_info() return json.dumps(track)
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 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 index(self): """sonos_menu, menu om commando's aan sonos te geven en info op te halen """ # verbinding maken met sonos sonos = SoCo(COORDINATOR) # wat speelt er nu, als het nummer niet uit playlist komt, is current_track niet gevuld current_song = sonos.get_current_track_info() current_track = int(current_song['playlist_position']) # haal queue uit database op self._db = MyDB() query = """select * from queue order by queue_id""" records = self._db.dbGetData(query) # print 'queue records', records # haal pagina op h = queuebeheer_temp.sonos_playmenu(records, sonos, current_track) return h
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()
class SonoHunter: banner = '''--- SonoHunter ---\n''' def __init__(self): self.connected_device = None self.translator = TextToSpeech() def print_banner(self): print_cyan(self.banner) def print_help(self): print("\nAvailable commands:") print("\n - " + "\n - ".join(self.logic.keys()) + "\n") def get_wlan_ip(self): return netifaces.ifaddresses('wlan0')[netifaces.AF_INET][0]['addr'] def connect(self, address): try: self.connected_device = SoCo(address) self.connected_device.player_name print_green('Connection active') except ConnectionRefusedError: self.connected_device = None print_red( 'Connection Failed: connection refused to {}'.format(address)) except OSError: self.connected_device = None print_red('Connection Failed: device {} not found'.format(address)) def play_file(self, file_name): if self.connected_device is None: print_red('Not connected') return if not os.path.isfile(file_name): print_red('File not found') return port = 8080 server = http.server.HTTPServer(('0.0.0.0', port), http.server.SimpleHTTPRequestHandler) print("Starting server") _thread.start_new_thread(server.handle_request, ()) self.connected_device.play_uri('http://{}:{}/{}'.format( self.get_wlan_ip(), port, file_name)) track = self.connected_device.get_current_track_info() print('playing {}'.format(track['title'])) self.connected_device.play() def refresh_logic(self, devices): available_device_names = {dev['player_name']: None for dev in devices} available_device_names.update({dev['ip']: None for dev in devices}) self.logic = { 'help': None, 'say': None, 'volume': None, 'quit': None, 'stop': None, 'scan': None, 'connect': (available_device_names), 'play': {x: None for x in os.listdir() if os.path.isfile(x)} } readline.set_completer(DeviceCompleter(self.logic).complete) def print_active_devices(self): self.scan_active_devices() devices = self.active_devices print("Active devices found: ") if devices == []: print_red("None") else: for device in devices: print_green("{}: {}".format(device['player_name'], device['ip'])) print() def scan_active_devices(self): print(" Hunting for devices ...\n") interface = "wlan0" ifaddrs = netifaces.ifaddresses(interface)[netifaces.AF_INET][0] ips = str( ipaddress.IPv4Interface(ifaddrs['addr'] + "/" + ifaddrs["netmask"]).network) start_time = datetime.now() conf.verb = 0 ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ips), timeout=2, iface=interface, inter=0.01) sonos_macs = [ "00:0E:58", "5C:AA:FD", "78:28:CA", "94:9F:3E", "B8:E9:37" ] devices = [{ 'mac': recv.sprintf("%Ether.src%"), 'ip': recv.sprintf("%ARP.psrc%") } for sent, recv in ans] sonos_devices = [] for device in devices: if (device['mac'][:8].upper() in sonos_macs): device['player_name'] = 'Error' try: device['player_name'] = SoCo(device['ip']).player_name sonos_devices.append(device) except e: print(e) self.active_devices = sonos_devices self.refresh_logic(self.active_devices) def say(self, words): if self.connected_device is None: print_red('Not connected') return file_name = "words.mp3" try: self.translator.convert_text_to_speech(words, file_name) except: print_red("Error generating file") return try: self.play_file(file_name) except: print_red("Error sending speech") def process_command(self, command): """ returns whether process should continue """ command_parts = command.split(" ") if command_parts[0] in ['?', 'help']: self.print_help() elif command_parts[0] in ['stop', 'quit']: return False elif command_parts[0] == 'scan': self.print_active_devices() elif command_parts[0] == 'connect': ip = '' try: ipaddress.IPv4Address(command_parts[1]) ip = command_parts[1] except ipaddress.AddressValueError: for dev in self.active_devices: if command_parts[1] == dev['player_name']: ip = dev['ip'] break try: self.connect(ip) except Exception as e: print_red('Error: {}'.format(e)) elif command_parts[0] == 'volume': try: if self.connected_device is not None: self.connected_device.volume = command_parts[1] except Exception as e: print("Invalid value") elif command_parts[0] == 'play': try: if len(command_parts) > 1: self.play_file(command_parts[1]) else: print("Invalid command") except Exception as e: print(e) elif command_parts[0] == 'say': try: if len(command_parts) > 1: self.say(" ".join(command_parts[1:])) else: print("Invalid command") except Exception as e: print(e) else: print("Command not found") return True def command_loop(self, commands=None): readline.parse_and_bind('tab: complete') readline.parse_and_bind('set editing-mode emacs') try: self.print_banner() if commands is None or commands == []: self.print_active_devices() else: for comm in commands: self.process_command(comm) should_continue = True while should_continue: should_continue = self.process_command(input('> ')) except KeyboardInterrupt as e: pass except EOFError as e: print(Fore.RESET + Style.NORMAL) print_red("\nQuitting")
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"
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: show_track(sonos)
hipChatRoom = None currentTrackInfo = None 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 >'
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
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
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()
#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']) }