Sonos plugin

Hi,

I have managed to create a Sonos plugin with basic functionality (version 0.1). As I am not a programmer whatsoever this has been made primarely based upon other plugins and code samles.

Hope you can use it. Feel free to contribute :slight_smile:

[size=14pt][size=10pt][b]
EDIT: Status and code no longer maintained in thris thread. The status and code has been moved to the
Plugin code site: Sonos Wireless HiFi Music Systems

[s]
This plugin allows you to control your Sonos via Vera scenes.

Development Status

  • Supported Models: ZP80 and ZP100 tested
  • Supported and tested features (no guaranties though):
    Supported Functions: Play, Pause, Stop, Previous, Next, IncreaseVolume, DecreaseVolume, Mute, UnMute, SetFileToPlay, SetVolume

What you need
-Vera with UI4 has only been tested, but at least one user has told me works on UI5.

Upload the plugin files:

  • In the Toolbox section open MiOS Developers >> Luup Files and upload all the files you downloaded. check the Restart Luup after upload checkbox and click GO.

Create the Sonos device:

  • Open Create Device.
  • In the UpnpDevFilename input box enter D_Sonos1.xml.
  • In the Description input box enter a name for the panel device, e.g. Sonos Livning Room.
  • Click Create device.
  • Close this window and Save.

Configuration

  • In the Sonos device advanced control tab specify the IP Address of your Sonos Zone in the ā€˜ipā€™ field.
  • Now actions are available in scenes.

/anker[/s]

FYI your created the repository as a private repository.

anker,

Thanks for sharing your code.

mcvflorin,

IMHO itā€™s a shame that Vera as a device that claims to be an UPnP<->Z-Wave bridge doesnā€™t work as advertised (http://bugs.micasaverde.com/view.php?id=1473). Vera even gets her own UPnP description wrong (http://bugs.micasaverde.com/view.php?id=1487)!

It could be as simple as

local answer = luup.call_action( 'urn:upnp-org:service:AVTransport', 'GetTransportInfo', { InstanceID = '0' }, sonos_device_id )
  • no need to resort to low level SOAP calls and custom Luup plugins ā€¦

Any chance to see a fix for #1473 soon?

I think this is considered low priority because very few users are affected by this, so I donā€™t think it will be fixed soon.

I think this is considered low priority because very few users are affected by this, so I don't think it will be fixed soon.

Letā€™s ask the users: :slight_smile:

[tt]http://forum.micasaverde.com/index.php/topic,8521.0.html[/tt]

Only a few users are affectedā€¦LMAO yeah right. Letā€™s see DLNA enabled TVā€™s, Sonos, and squeezebox. I think thatā€™s a lot of users.

@mcvflorin

Yeahā€¦Iā€™m going to have to go ahead and disagree with you. While I understand that not every user that buys a Vera wants this feature, a large number of your grass-roots developers do. Not having this is stopping me from creating 2-3 plugins. I would take two days off work to create the squeezebox plugin alone.

I have several friends who come over and are impressed with my home automation. However, I canā€™t in good conscience recommend my setup to any of them because, unlike me, they are not willing to write plugins for everything they own. If you would fix these bugs and stop treating your open-source developers like they are a burden, maybe you would have the plugin explosion you were looking for the last few years.

I also know that its not you personally. You write plugins and help where you can. Its more the management at MCV. I suspect you get as frustrated as the rest of us as well.

@anker,
What do you most need assistance with in Developing this? I donā€™t have a Sonos, but Iā€™ve done a bunch of the AV Plugins so I know how to hook up those parts so theyā€™ll be exposed in Control Points like SQRemote, or others that understand the AV extensions.

Also, if you let us know your dev platform, Iā€™m sure there are a few people that can recommend a Graphical interface to get your stuff into SVN (behind code.mios.com for your code).

PS: I modded the permissions on your code.mios.com space so that the Wiki will now display without requiring people to login.

@anker,
Got your PM, so Iā€™ll respond here. Iā€™ve taken the liberty of adding the first generation of your code to your existing code.mios.com space:

http://code.mios.com/trac/mios_sonos-wireless-music-systems

This should help us ā€œdiffā€ things over time as changes are added.

Does anyone in the community have a Windows machine they run a GUI shell for SVN that they can make a recommendation?

eg. TortoiseSVN

My preference would be something that has Windows Explorer integration, so folks like @anker can Right-click Checkin in the File manager (to get them going quickly)

The first round of changes Iā€™d like to make are:
a) the additions of the standard AV ServiceID (and sections)
Iā€™d add these for each of the calls you currently have, so you can see the pattern for future ones.

b) change the TAB characters into 2-sp or 4-sp indentation.
TABs expand to 8-ch in my editor by default, so it makes your code look wide and oddly formatted.

c) Maybe pull out the SOAP stuff into a Lua Library for future share-ability
Thisā€™ll also help with all the ā€œencodingā€ stuff you currently have to deal with (>, <, etc) in the file because the Luup Device files are XML. Itā€™ll make the code a lot more readable for intent.

Let me know if youā€™re ok with me making these tweaks.

BTW, even if youā€™ve not programmed before, youā€™ve definitely got the hang of gluing all the relevant pieces together, congrats!

hi guessed,

Feel free to make those changes. I am especially looking forward to the standard AV integration bit - even though I am not sure what it actually meansā€¦ :slight_smile:

Maybe you can let me in on what coming out of this.

Pls let me know what priorities there are functionality wise towards Sonos and I will have a look at this.

Regards

anker

So nice to see things happening on the Sonos front! :slight_smile:

Are there any plans on zone management (adding/removing)? I.e. when I switch on the light in bathroom, the unit is added to my main zone, and starts playing.

Another nice thing would be to start playing a specific file on a specific player. Example: Play dog barking when PIR sensor trigs outsideā€¦ Dog getting louder and more lunatic when/if more PIR sensor triggers. Moving dog sound all over the house.

Should scare any thief awayā€¦

@anker,
Iā€™ve made a bunch of changes this evening, most of these are outlined in the latest changeset block:
Changeset 5 ā€“ Sonos Wireless HiFi Music Systems

I can only test that the basic principals of the code are working, as I donā€™t have a Sonos. I can test some basic stuff by pointing it at the IP/Port and Service URIā€™s for my Onkyo Receiver but that really only tests basic communication and thereā€™s a bunch of could have gotten wrong given the surgery that I did on it.

I did validate that the Volume/Mute and Stop/Play/Pause/SkipUp/SkipDown appear to show up correctly in the Picklists in SQRemote now theyā€™ve been moved to the standard/conventional MiOS based ServiceIdā€™s.

Can you make a backup of what you have, and then download the ZIP Archive of trunk from:
http://code.mios.com/trac/mios_sonos-wireless-music-systems/changeset/5/trunk?old_path=%2F&format=zip

and try it out?

For testing purposes, Iā€™ve mostly been using standard [tt]lu_action[/tt] style URLā€™s directly against Vera, and then looking at the [tt]LuaUPnP.log[/tt] as I do.

PS: For reference, in MiOS, there are a set of ServiceIdā€™s that come pre-packaged with Vera that are MiOS-specific AV bundles. They typically represent groupings of logical remote-control buttons for things like [Volume]Up/[Volume]Down, Mute (toggle), Play/Pause etc

Part of what Iā€™ve done here is to map those [MiOS] ā€œstandardā€ ones, where they exist, to the UPnP APIā€™s - avoiding the need to create as extensive of a [tt]S_Sonos1.xml[/tt] file. It also means they show up in SQRemote, which goes looking for theseā€¦ so you donā€™t need to write code to use them, unlike regular UPnP hooks which require Lua coding to do anything useful.

Over time, as stuff is added here, more ā€œadvancedā€ use-cases may need to get exposure to the underlying bits, but it can mostly be simple/declarative for now.

Currently there is no JSON file, so these ACTIONs cannot be picked for use as Commands in Scenesā€¦yet

A more general approach would be to write a reusable ā€œUPnP device descriptionā€ to ā€œLuup deviceā€ compiler plugin.

All required pieces are there:

[ul][li]UPnP specification: http://upnp.org/resources/upnpresources.zip[/li]
[li]SOAP request from Luup code: [tt]http://forum.micasaverde.com/index.php/topic,7707.msg49534.html#msg49534[/tt][/li]
[li]Example compiler plugin: [tt]http://forum.micasaverde.com/index.php?topic=5709.0[/tt][/li][/ul]

I wonā€™t do it myself, because IMHO the U2L compiler plugin is another workaround for a basic bug in MiOS that would free MCV from the need to provide a fix for [tt]http://bugs.micasaverde.com/view.php?id=1473[/tt].

Thankyou for you input.

The first round of changes were geared around:

[ul][li]moving towards using the MiOS-based AV entry points.
This enables UIā€™s like SQRemote (etc) to pickup the device and control it in rudimentary ways. Without this mapping, itā€™s just a bunch of dumb ACTION hooks, with maybe a Local-to-Vera UI, and thatā€™s about it. I wanted it correctly extended out so it could readily be used with AV-enabled Remotes.
[/li]
[li]elimination of the ā€œexecā€ process for making [tt]HTTP-POST[/tt] operations.
The use of exec here is too simple minded, esp since these calls will be run frequently (via a Remote). I wanted something that was going to be faster/in-process, and not have the conc problems that the exec implementation had.
[/li][/ul]

Over time, I plan on extracting out the UPnP bits as a Library. But rather than trying to implement the whole spec, Iā€™ll just focus on those bits that people need, and people can add others as the find need for additional ones. Itā€™s fairly simple marshalling code, and that change will cleanup/simplify the Plugin itself. But thereā€™s a few things that are needed prior to that (like a JSON file)

Thereā€™s really no need for a generator since thereā€™s a bounded amount of input to it, unlike what you have in the LIRC and I have in the SQController stuff. Youā€™d spend more time writing a UPnP ā†’ Lua Stub compiler than hand-translating the few/fixed APIā€™s that are really needed. A generator for the event section of a JSON maybe, but that can also be done C&P style.

But even with the Library, the Plugin itself is still needed, in order to map from the ā€œcodeā€ of the UPnP actions over to Declarative nature of the Plugin (for usability by the masses). Even with the simple set of functions today, there are already impedance mis-matches that need to be fixed.

eg. Toggle Mute (MiOS) vs Discrete Mute (UPnP)

I figured this approach would get be there faster than waiting on the side-lines for a bug fix. If you ever change your mind, and would like to contribute code to the effort, then let me know and Iā€™ll open up the code space to you.

Iā€™m one who would be interested in Sonos control through Vera, but only in certain ways. Sonosā€™ software controller is excellent, and that would likely be my usual, casual controller. But I would be interested in certain things:

Pick specific sources, specific playlists or streams through scenes. For example, the good morning scene would play a news radio stream at X percent volume in the bathroom only.

The goodnight scene (timer) could stop (or pause) any playing media and mute all players in the house.

Looking forward to seeing what you come up with!
Dave

[quote=ā€œDaveL17, post:15, topic:169644ā€]Iā€™m one who would be interested in Sonos control through Vera, but only in certain ways. Sonosā€™ software controller is excellent, and that would likely be my usual, casual controller. But I would be interested in certain things:

Pick specific sources, specific playlists or streams through scenes. For example, the good morning scene would play a news radio stream at X percent volume in the bathroom only.

The goodnight scene (timer) could stop (or pause) any playing media and mute all players in the house.

Looking forward to seeing what you come up with!
Dave[/quote]

Hi Dave,

You are able with the current version to stop, play, pause or mute any sonos zone. The other requests will be good inspiration for further development :slight_smile:

/anker

[quote=ā€œguessed, post:14, topic:169644ā€]Thankyou for you input.

The first round of changes were geared around:

[ul][li]moving towards using the MiOS-based AV entry points.
This enables UIā€™s like SQRemote (etc) to pickup the device and control it in rudimentary ways. Without this mapping, itā€™s just a bunch of dumb ACTION hooks, with maybe a Local-to-Vera UI, and thatā€™s about it. I wanted it correctly extended out so it could readily be used with AV-enabled Remotes.
[/li]
[li]elimination of the ā€œexecā€ process for making [tt]HTTP-POST[/tt] operations.
The use of exec here is too simple minded, esp since these calls will be run frequently (via a Remote). I wanted something that was going to be faster/in-process, and not have the conc problems that the exec implementation had.
[/li][/ul]

Over time, I plan on extracting out the UPnP bits as a Library. But rather than trying to implement the whole spec, Iā€™ll just focus on those bits that people need, and people can add others as the find need for additional ones. Itā€™s fairly simple marshalling code, and that change will cleanup/simplify the Plugin itself. But thereā€™s a few things that are needed prior to that (like a JSON file)

Thereā€™s really no need for a generator since thereā€™s a bounded amount of input to it, unlike what you have in the LIRC and I have in the SQController stuff. Youā€™d spend more time writing a UPnP ā†’ Lua Stub compiler than hand-translating the few/fixed APIā€™s that are really needed. A generator for the event section of a JSON maybe, but that can also be done C&P style.

But even with the Library, the Plugin itself is still needed, in order to map from the ā€œcodeā€ of the UPnP actions over to Declarative nature of the Plugin (for usability by the masses). Even with the simple set of functions today, there are already impedance mis-matches that need to be fixed.

eg. Toggle Mute (MiOS) vs Discrete Mute (UPnP)

I figured this approach would get be there faster than waiting on the side-lines for a bug fix. If you ever change your mind, and would like to contribute code to the effort, then let me know and Iā€™ll open up the code space to you.[/quote]

@guessed.

Fine with the entry points. they now show up in scenes advanced when installing your corrected files.

The http operation seems to have a problem though. Nothing happens on any of the actions. My log in debug line 56 shows:

debug SOAP_request: status=no status statusMsg=timeout result=[]

Dont know what that actualy means.

The toggle mute needs to read status on the sonos - you cannot assume that Mute is trueā€¦

This Sonos upnp calls should be used: RenderingControl - ā€œGetMuteā€ with arguments (InstanceID, Channel, CurrentMute) where CurrentMute is a boolean returned.

Apart from this is looks good. What SONOS actions do you think I should prioritize?

N.B: SkipDown - should it be the same as Previous - did you flip this (and the SkipUp) or am I just confused?

/anker

[quote=ā€œanker, post:16, topic:169644ā€]Hi Dave,

You are able with the current version to stop, play, pause or mute any sonos zone. The other requests will be good inspiration for further development :slight_smile:

/anker[/quote]
I guess development is further along than I thought!

Dave

There's really no need for a generator since there's a bounded amount of input to it, unlike what you have in the LIRC and I have in the SQController stuff. You'd spend more time writing a UPnP -> Lua Stub compiler than hand-translating the few/fixed API's that are really needed.

It depends on which UPnP enabled devices you are going to control from Vera. Yes, the amount of UPnP devices defined by the UPnP Forum is bounded, but not all UPnP devices are defined by the UPnP Forum, e.g. [tt]IntegraciĆ³n de Rovio en una red UPnP - YouTube.

For a complete and user-friendly workaround for bug http://bugs.micasaverde.com/view.php?id=1473, a compiler is needed.

You'd spend more time writing a UPnP -> Lua Stub compiler than hand-translating the few/fixed API's that are really needed. A generator for the event section of a JSON maybe, but that can also be done C&P style.

Depends on your coding and C&P skills :slight_smile: - and donā€™t neglect the time required to debug the files created manually. :wink:

The http operation seems to have a problem though. Nothing happens on any of the actions. My log in debug line 56 shows:

debug SOAP_request: status=no status statusMsg=timeout result=[]

Dont know what that actualy means.

It means that the new HTTP tried to call the underlying URL but it timed out with no response from the Sonos, after 5 seconds, instead of providing a result. Iā€™ll add more debugging in to print out the URIā€™s itā€™s running.

When I was trying this last night, it would do that when I had the wrong address, or port, but Iā€™m assuming you rolled over your IP configuration so thatā€™s not likely the problem.

Youā€™ll see commented out code near the top that I was using to check the raw calls against my Onkyo (port 8888, and different control URIs) so I know that the basic connectivity is working from the new lib, including send/recv.

Iā€™ll use WireShark to compare what the CURL command was sending against what socket.http lib sends and see if thereā€™s a material difference.

The toggle mute needs to read status on the sonos - you cannot assume that Mute is true...
Yes, that's why my Checkin comment indicates:
Implement a rough/crude Mute toggle, as required by micasaverde-com:serviceId:Volume1 / Mute
It's a stub impl for now, but it needs to be rounded out. There are a few ways to do that, including [synchronously] calling [i]GetMute[/i] prior to doing what it currently does, or "observing" it via UPnP events (no framework yet)... It was more a stub for the moment, to meet the need. Any real "user" can simply press Mute until it actually does get into sync, at least until a better model can be impl ;-)

But yes, it can be done better.

Apart from this is looks good. What SONOS actions do you think I should prioritize?
No idea, I don't have a Sonos but I figured folks that do will chime in.

Youā€™ll probably need to experiment a little to work out how to do some of the input tricks that @DaveL17 is looking for, and Iā€™d like to know how you measure the current Volume, and whatā€™s currently playing, so I can add it into the Dashboard display. On my Onkyo Receiver, these come as Events so I change the values as they come in. Itā€™s likely Iā€™ll need to Poll, for now, to get them working on the Sonos (again, until Events are sorted)

N.B: SkipDown - should it be the same as Previous - did you flip this (and the SkipUp) or am I just confused?
I picked "[i]SkipDown[/i]" for [i]Previous[/i], and "[i]SkipUp[/i]" for [i]Next[/i]. It's just one convention, I have no problem if you'd prefer them the other way around. There were no native Previous/Next, so I used these instead ;)