rahims / soco Goto Github PK
View Code? Open in Web Editor NEWSoCo (Sonos Controller) is a simple Python class that allows you to programmatically control Sonos speakers.
SoCo (Sonos Controller) is a simple Python class that allows you to programmatically control Sonos speakers.
I would be interested in knowing what music services people are using that way if there are a few shared services I can work on those first. Here is what I use
Pandora
Spotify
Slacker
First of, thank to rahims for creating the project and to everyone else who has contributed. It looks to be a promising project.
Since there seem to be a great deal of development activity, I thought it would be helpfull with some unit tests of the soco methods, to watch out for regressions.
I'm already working on it and I'm posting mostly to avoid double work. If anyone else is working on something like this, please let me know.
I found a good way to stream songs from SoundCloud to my Sonos, but unfortunately it doesn't really work with this (very cool) API. Any idea why this does happen?
>>> track = sonos.get_current_track_info()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.macosx-10.9-intel/egg/soco.py", line 680, in get_current_track_info
AttributeError: 'NoneType' object has no attribute 'encode'
I'm not a python pro, that's why I can't fix it.
Currently the library causes a crash when it encounters a zone bridge. The zone bridge only returns ZPSupportInfo but does not return ZPInfo. So the code that assumes this is returned get_speaker_info throws an exception.
DEBUG:requests.packages.urllib3.connectionpool:"GET /status/zp HTTP/1.1" 200 None
Traceback (most recent call last):
File "./sonos.py", line 26, in
zone_name = device.get_speaker_info()['zone_name']
File "/root/cps/shared/soco.py", line 648, in get_speaker_info
self.speaker_info['zone_name'] = dom.findtext('.//ZoneName').encode('utf-8')
AttributeError: 'NoneType' object has no attribute 'encode'
Hi everyone
Lately there has been quite a lot of interest in the development of SoCo and therefore I am opening this discussion about moving the development to a group project. The advantages as I see them are:
Just to make sure that this doesn't come of in the wrong way (internet communication can be tricky sometimes). This suggestion is not about lobbying for more influence or commit rights to the "official" repo or anything like that. The project was formed by @rahims and I think he has done a completely awesome job of founding and maintaining it ;) so if we were to make this change it could perfectly well be made with @rahims as the only member of the group to make for a situation equivalent to the one we have today. But the point about it being flexible is that it will then be possible e.g. to delegate during real life busy periods.
Best Regards Kenneth
Hi Rahim,
Great stuff. Really nice! You should change your name to Sonoswalla!-))
I've written my own Zonos controller, with the long term aim to at least provide the same interface to my computer (aka add it as a virtual Zone player). Having some thoughts on ensuring party-mode would work using frequency analysis and cross-correlation of the sound-track. That's still down the track. Currently, my controller does everything (I've had time to program), but I do have one incy wincy little itemette. Having 18000+ tracks it takes hell-of-a-time to build a list of all tracks (i.e. looping with get_music_lib with 300 items at a time). Now hooking up my iphone, it got the list in a wazzle-dazzle, so there must be a better way of doing it.
Any suggestions?
Cheers
Ken
While writing a unit test for the get_speakers_ip method I discovered that it does not work on my computer. The second line below caused an AttributeError for the attribute "text".
response = requests.get('http://' + self.speaker_ip + ':1400/status/topology')
text = response.text
Maybe the reason is different versions of the requests library, where this attribute is no longer present.
I have written a fix for it in this code branch https://github.com/KennethNielsen/SoCo/commits/fix_get_speakers_ip. This fix replaces the .text with .content attribute the way it is used in all the other methods (commit 3eb8f5c)
While I had my hands in this methid I also made a few suggested changes for it. For these changes we should probably discuss if they should be merged:
Commit e5639e6 changes the method so that it uses the fact that it is xml it gets back, to parse its way directly down to the ZonePlayer tags. This, I think, should remove the need to check the status of the found ip's (to exclude media servers) the way it was done before, and these check have therefore been removed.
Commit b22f2f8 renames the method and the class variable to ..speaker_ips instead of speakers_ip to make it consistent with the SonosDiscovery class (and I think also makes it more correct English, apparently the plural s should be on the most significant of the nouns in a compound noun, which in this case I believe is the ip)
http://[Sonos player IP]:1400/status
Lot's of interesting information, including the player's temperature and free memory ๐
I've packaged SoCo for PyPI some time ago (http://pypi.python.org/pypi/soco). The published version is, however, still 0.1 and thus quite outdated, as we seem to be at 0.5 right now. I'll update the package soon, but I'd like to propose and discuss the workflow first.
I assume that the job of versioning will be done by @rahims, right? If so, I'd like to agree on some procedure for that. My suggestion:
Having a tag for each version makes it very easy to use GitHub's compare view to create a simple change log (commit range between current and previous tag).
I'd be very happy about some feedback!
https://pypi.python.org/pypi/soco/0.6
SoCo there points here, but the version there is 0.6 and the source layout is different.
Is SoCo's source still hosted here?
I'm planning on using SoCo for https://github.com/anonfunc/remote/
Hi
It would be nice to get the radio logo.
I think it will work when you parsing this directly from tunein
with
http://opml.radiotime.com/Describe.ashx?c=nowplaying&id=${ID}&partnerId=Sonos&serial=${SONOS_SERIAL}
the id you become from the radio request return
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
<item id="R:0/0/0" parentID="R:0/0" restricted="false">
<dc:title>105.9 | Power 106 (Hip Hop)</dc:title>
<upnp:class>object.item.audioItem.audioBroadcast</upnp:class>
<res protocolInfo="x-rincon-mp3radio:*:*:*">x-sonosapi-stream:s34767?sid=254&flags=32</res>
</item>
</DIDL-Lite>
the id isin this example the s34767
Great project - really enjoying it.
Because the volume can get or set volume it sets the value to False when getting volume.
Setting the volume to 0 is also interpreted as False so you can never set volume to 0.
Fix suggested by Kenneth Nielsen is to use the None Type as follows:
def volume(self, volume=None):
''' '''
if volume is None:
rest of code.......
etc......
have tested and it works fine
Cheers David
Hello,
i get the following error after this command: python sonoshell.py 192.168.10.27 play. Why?
Traceback (most recent call last):
File "sonoshell.py", line 34, in
print sonos.play()
File "/usr/local/lib/python2.7/dist-packages/soco/core.py", line 439, in play
('Speed', 1)
File "/usr/local/lib/python2.7/dist-packages/soco/services.py", line 158, in _dispatcher
return self.send_command(action, _args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/soco/services.py", line 330, in send_command
self.base_url + self.control_url, headers=headers, data=body)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 94, in post
return request('post', url, data=data, json=json, *_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 49, in request
return session.request(method=method, url=url, *_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 457, in request
resp = self.send(prep, *_send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 569, in send
r = adapter.send(request, *_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 407, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(113, 'No route to host'))
Hi,
I moved all my stuff from my macbook air (working fine) to my imac. I now get the following error for mute ('bool' object is not callable) and a similar one for volume ('int' object is not callable).
After some browsing and testing it seems that using the function
sonos.mute which declares an internal variable as mute, causes the inconsistency between callable function and variable. If I change the function name from mute to mutt all is fine. Or other way around, change the internal variable from mute to muted again all is good. You may want to consider an update here in case my observation is correct. Same goes for volume but I don't know if it occurs elsewhere too.
Cheers
Ken
First Thanks for this nice python class. It works very nice.
I am working on on a web page which includes sonos.
Please can you implement a new feature. It would be nice to become a list of the Favorite radio station.
When I startet sonos new or on one zone was display 'no Musikfile' then the parser give me an error.
File "/mnt/Media/Downloads/Homematic/core/DBFunctions.py", line 379, in UpdateSonosTable
devices = Sonos().GetTrackInfo()
File "/mnt/Media/Downloads/Homematic/core/module/sonos.py", line 36, in GetTrackInfo
track = sonosdevice.get_current_track_info()
File "/mnt/Media/Downloads/Homematic/lib/sonos/soco.py", line 588, in get_current_track_info
metadata = XML.fromstring(d.encode('utf-8'))
File "", line 107, in XML
ParseError: no element found: line 1, column 0
perhaps one try except will fix this :-)
Hallo
I was wondering whether anyone else would be interested in an IRC channel for soco. I think that every once in a while, there are some things that could be better solved via IRC. There should of course be no obligation to how much time people use on the channel, but just whenever we feel like it.
What do you think?
Here is the Traceback
Traceback (most recent call last):
File "test.py", line 7, in <module>
items = sonos.get_favorite_radio_stations(start=0, max_items=9)
File "/mnt/Media/Downloads/Homematic/lib/sonos/soco.py", line 840, in get_favorite_radio_stations
return self.__get_radio_favorites(RADIO_STATIONS, start, max_items)
File "/mnt/Media/Downloads/Homematic/lib/sonos/soco.py", line 858, in __get_radio_favorites
dom = XML.fromstring(response)
File "<string>", line 106, in XML
UnicodeEncodeError: 'ascii' codec can't encode character u'\xd6' in position 3372: ordinal not in range(128)
This error come by parsing the name 'ร2 Radio'
Hallo
I'm not quite sure what happened. Yesterdayn while I was working on the unittests and using the get_queue method I decided to merge upstream master into my branch and after that the get_queue method did not work anymore. At first I thought that maybe I had done something wrong (I'm a bit of a git newbie) so then I cloned a fresh copy of upstream and I still have the problem.
Can anyone else confirm if this method works for them with the current upstream master?
The exact data that was used in the request and the return value are as follows:
### ADDRESS
http://192.168.0.110:1400/MediaServer/ContentDirectory/Control
### DATA
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1#Browse"><ObjectID>Q:0</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter>dc:title,res,dc:creator,upnp:artist,upnp:album,upnp:albumArtURI</Filter><StartingIndex>0</StartingIndex><RequestedCount>100</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>
### HEADERS
{'SOAPACTION': '"urn:schemas-upnp-org:service:ContentDirectory:1#Browse"', 'Content-Type': 'text/xml'}
### RETURN
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><s:Fault><faultcode>s:Client</faultcode><faultstring>UPnPError</faultstring><detail><UPnPError xmlns="urn:schemas-upnp-org:control-1-0"><errorCode>402</errorCode></UPnPError></detail></s:Fault></s:Body></s:Envelope>
###
Alternatively I must have seriously messed something up with my computer, because I don't think it is the sonos device that is acting up, because I can read the queue both with the android and web client.
Requested by @labero through e-mail.
Would be very useful for those building GUI clients if they could get notifications when events occur, such as a song change.
Hello
Using Soso and have a question about commands.
SonosSoCo.get_current_track_info() lets report the informations of the current track where i can read the informations like artist album title thats all okay
SonosSoCo.get_queue() lets report the playlist as queue but i cant pick out the information about the next track
Is there an command for getting just the information of the next track
Regards
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.