Sonos plugin

And probably more important than the service variables would be to describe available service actions with a description of the arguments (which ones need to be filled in particular).

Baby steps. I started with these because I was already doing the writeup of the ones that were being obsoleted, and needed to provide the counterparts.

The Wiki is open to you, so you can directly add whatever you want to it. I may not get to full doc for the Service Variables this weekend as I have to switch back to work mode.

The timing varies by call, and what else Vera has going on. In mine, I have 3x Sonos units that are polling, along with a lot of data coming from my Brultech Power monitors. These all come every i15-60 seconds so there’s a fair amount of background “load” going on.

So yes, my summary is that the file we’re generating isn’t long enough. I suspect that if it was a LOT longer then we’d see it play almost immediately (after our overheads for save).

Anyone wanting it to go-faster will probably need to pre-create the files, and shift them manually over to a NAS of their choice (not Vera). Since most of this TTS stuff is for “static” messages, this would be fine.

I tested this last night by putting one of the “Say*.mp3” files directly onto my Mac, and requesting the Sonos to pull it down. It didn’t need to be indexed first, it worked correctly.

CIFS is available for OpenWRT, but it’s likely too much headache for the average user to get going.

[quote=“lolodomo, post:739, topic:169644”][quote=“guessed, post:737, topic:169644”]The content from Vera’s lighttpd has the correct content-length header, and it’s using Keep-Alives so the connection stays “open” at the end of the download for ~5s before it’s terminated.

I suspect that the Sonos unit, driven by the “[tt]x-rincon-mp3radio[/tt]” directive, is waiting for more stuff to come down and fill it’s buffers… and only starts playing it once we hit the FIN on the connection.[/quote]

So the problem would be the small file size of the generated files ?

If true, then the only way to "fix" the delay would be to find an alternative to the "mp3-radio" style of download, or [potentially] to provide Sonos with the supporting metadata to let it know what the length is (previously experimented with no luck).

The last option, for those wanting fast TTS, is to move them to a NAS, since these always play fast, and manually use the save & restore hooks.

You mean downloading the file in a CIFS share ? I think that would require a media library index update after each download and so some time ?
Do you know if we can create a CIFS file share in the Vera ? For example, we could have the directory /www/TTS as a CIFS share.

BTW: In my rough timings, we add ~1000ms to "save" the state prior to playing. Most of this is lost in the various synchronous UPnP calls made to get the most-recent state. We could probably reduce this by providing an option of "tolerance" that's used to work out if we need to re-fetch all the values, or just store "the last known set" that we have (as long as it's within a tolerance)

That is something I have not measured. I did not think it take 1 second. Considering what is saved in the context, here are the minimum calls required:
AVTransport.GetTransportInfo
AVTransport.GetTransportSettings
AVTransport.GetCrossfadeMode
AVTransport.GetCurrentTransportActions
AVTransport.GetMediaInfo
AVTransport.GetPositionInfo
Rendering.GetMute
Rendering.GetVolume
So we could at least avoid 4 calls to Browse.
Call to AVTransport.GetCurrentTransportActions could probably be suppressed and replaced by the same call in the restore function.[/quote]

I haven’t much changes to the default installation in my Vera. Could I mess up something if I install CIFS?

opkg install kmod-fs-cifs

@hek,
The CIFS functionality is part of OpenWRT, so it’s definitely loadable, and configurable, but it’s not as “out of the box” as we’d want for general use.

The last time I checked, for example, MCV “pointed” their [tt]opkg[/tt] repos at a non-standard URL so you had to tweak it to get to the real one that had all the fun stuff in it. 8)

Then there’s all the stuff about “non support” in their banners, so you’d be on your own from that perspective as well… not that it deterred anyone in the past, except when it comes to fault-finding why something bad occurred on the box.

[quote=“guessed, post:743, topic:169644”]So yes, my summary is that the file we’re generating isn’t long enough. I suspect that if it was a LOT longer then we’d see it play almost immediately (after our overheads for save).

Anyone wanting it to go-faster will probably need to pre-create the files, and shift them manually over to a NAS of their choice (not Vera). Since most of this TTS stuff is for “static” messages, this would be fine.[/quote]

Yes, for static messages, that is a solution. But for dynamic messages, we have no other solution than calling Google in real time.

I tested this last night by putting one of the "Say*.mp3" files directly onto my Mac, and requesting the Sonos to pull it down. It didn't need to be indexed first, it worked correctly.

Good to know.
Update is probably required only to see the files as part of the media library. And we don’t care about that.

CIFS is available for OpenWRT, but it's likely too much headache for the average user to get going.

I agree.
Other alternative, not easier for the average user, would be to mount the first Sonos share in the Vera and then download the Google file to the share folder. Maybe we can even make this mount automatically ?

Two thoughts

  1. Could an external USB drive be an option? I (and a number of others may) already have one for things like logs or dataMine?

  2. Could the saved file names be done in such a way that when any future ‘say’ command is run, the plugin first checks if a file of the same name (from a previous request) already exists and then plays that, if not, then it goes off to Google and downloads a new one.

@parkerc,
The external USB is only part of the issue. Once you have it, you still need the CIFS stuff installed in order to “expose” the files from it as a [shared] filesystem to the Sonos units (and configure the Sonos units to “know” about it).

This is all technically do-able, but it’s complicated for the average punter… and if something goes amiss, it’s hard to debug.

I had considered the cache of “Say” output, and almost implemented it. The trick here is that if you start saying dynamic things then the filesystem will fill up with a long list of files. Something then needs to come along and “clean” these out. This clean-out needs to occur faster than the FS might fill up, or all hell will break loose on Vera.

The other option I’d considered was a “hash” of what you’re trying to “Say”, which would cap the overall # of files. It would, however, need a short(ish) directory to keep track of what’s in the cache, which just seemed like overkill for what this thing does.

Thanks for the re-cap @guessed, you’re right achieving a good balance between function and form is key…

I know how to get the different shares of the Sonos (Browse call). Isn’t it possible to mount automatically one of these CIFS shares in the Vera using a mount command ?
Then, we have only to download the Google file in this CIFS share rather than in /www and finally play it.

Yes, all possible, but it’ll require:

a) The kmod for CIFS to be installed into Vera (for client-side mounting)
b) A read-write Filesystem on some remote machine (the Music shares are typically Read-only)
c) The remote machine to be running in an Always-on mode at the time of the calls

I bias towards running on Vera, in some capacity, because of the setup required to get this all “working” correctly for people. Also, in my case, Item (c) isn’t always possible since I idle-down all my machines when not actively used.

[quote=“lolodomo, post:750, topic:169644”]I know how to get the different shares of the Sonos (Browse call). Isn’t it possible to mount automatically one of these CIFS shares in the Vera using a mount command ?
Then, we have only to download the Google file in this CIFS share rather than in /www and finally play it.[/quote]

Point a) is sufficient for me to forget this alternative ;D

If keep-alive is the problem we could try to set the property server.max-keep-alive-idle to 0 in
/etc/lighthttpd.conf

Or perhaps create a small cgi-script serving the mp3 under /www/cgi-bin/cmh/ and point the sonos to this instead.

Not sure if it helps stopping the delay… but we could probably modify get_file.sh to something like this:

#!/usr/bin/haserl
<?
echo "Content-type: audio/mpeg"
echo "Content-disposition: attachment; filename=tts.mp3"
echo ""

if [[ -z $FORM_filename ]]; then
    echo "File not specified."
else
      cat "/www/<our file path>.mp3"
fi
exit 0

Have to try tomorrow when the family isn’t asleep…

Well, thanks to a post on the Homeseer board:
http://board.homeseer.com/showthread.php?t=155033

I did manage to find out how to stop the “Say” command repeating it’s content. It just needs a well-formed DIDL-Lite entry, like in this example:

luup.call_action('urn:upnp-org:serviceId:AVTransport', 'SetAVTransportURI', {CurrentURI='http://192.168.6.66:80/Say.666.mp3', CurrentURIMetaData='<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="-1" parentID="-1" restricted="true"><res protocolInfo="http-get:*:audio/mpeg:*">http://192.168.6.66:80/Say.666.mp3</res><r:streamContent></r:streamContent><upnp:albumArtURI>http://www.mios.com/wp-content/themes/miostheme/images/google-logo-square.png</upnp:albumArtURI><dc:title>Vera SayIT</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:creator>Vera Sonos Plugin</dc:creator><upnp:album>MiOS</upnp:album><r:albumArtist>Vera Sonos Plugin</r:albumArtist></item></DIDL-Lite>'}, 666) luup.call_action('urn:upnp-org:serviceId:AVTransport', 'Play', {}, 666)

It still has the timeout-oriented delays mentioned earlier, but it steps closer to a cleaner setup.

A slightly wilder idea… if we get fancy with injecting a cgi-script execution to “return” this content, instead of the Raw filesystem, it may be possible for us to send a command/event back to Vera to tell us when the download (or placeholder download) is finished so we can restore the context (etc)

That’ll avoid all of the timing-based delays that we currently have.

ie. We’d add the “Say” to the queue, then add a “marker” file after it, and play both. When the Marker file is downloaded, we’d [hopefully] know that the regular Say file had been played (assuming no buffering)

@lolodomo,
A few UI quirks I noticed when I ran up the UI5 Dashboard on my iPad:

a) The new “Volume” control wraps like this:

[tt] (-)[0][0][0][0][0][ ][ ]
[ ][ ][ ][/tt]

b) The Player tab shows less information for Streaming Radio Stations than the Control Tab
In my case, on the Control tab it shows I’m listening to:
KLLC Alice 97.3: KLLCFM_SC:
but on the Player tab it only shows:
Stream: KLLCFM_SC
Information:

The [tt]CurrentRadio[/tt] serviceVariable correctly contains KLLC Alice 97.3, and the [tt]CurrentStatus[/tt] glueup contains KLLC Alice 97.3: KLLCFM_SC

[quote=“guessed, post:756, topic:169644”]@lolodomo,
A few UI quirks I noticed when I ran up the UI5 Dashboard on my iPad:

a) The new “Volume” control wraps like this:

[tt] (-)[0][0][0][0][0][ ][ ]
[ ][ ][ ][/tt][/quote]

Yes, same result with IE. Some browsers may force a minimum width for buttons.
As I have no time to check that, the solution would be to comment the volume management in the Javascript. I will do it.

b) The Player tab shows less information for Streaming Radio Stations than the Control Tab In my case, on the Control tab it shows I'm listening to: [i][b]KLLC Alice 97.3[/b]: KLLCFM_SC: [/i] but on the Player tab it only shows: [i]Stream: KLLCFM_SC Information: [/i]

The [tt]CurrentRadio[/tt] serviceVariable correctly contains KLLC Alice 97.3, and the [tt]CurrentStatus[/tt] glueup contains KLLC Alice 97.3: KLLCFM_SC

Interesting. I check immediately what’s different with this radio.

This radio seems to be different. I found it through the tunein web interface: KLLC-FM, 97.3 FM, San Francisco, CA | Free Internet Radio | TuneIn
But when I push the play button, instead of playing the radio, a new window is opened http://betaplayer.radio.com/player/alice-973/
I got advertising but the radio never started.

When I search the radio from the Sonos interface in San Francisco, I find Alice Radio, same log, everything is ok. But it is not KLLC Alice that is not found as a radio in San Francisco. So I don’t know how to select this radio with the Sonos interface.

@lolodomo,
Oops, forgot it was a custom-registered Favorites entry.

The details are:
[tt]CurrentURI[/tt] shows as: x-rincon-mp3radio://1331.live.streamtheworld.com:80/KLLCFM_SC
[tt]AVTransportURI[/tt] shows as: x-rincon-mp3radio://provisioning.streamtheworld.com/pls/KLLCFM.pls

For the Volume slider, if it could be tweaked to show less slider-segments (or reposition it) then it work work also.

I have committed a fix. Now you should see the station name of your Web Radio in the Player tab if this radio is selected from the Sonos application. I would have to do another change to not loose this station name when this Web radio is selected from the favorite list in the plugin UI.

Volume management in the Player tab has been disabled.