Sonos plugin

Could you incorporate my say length calculation (+ 2-3 seconds).

A also have a scenario where I want to pause eventual music playing (“save play context”) when someone is calling our house. Then the sonos should say who is calling (and keep music paused). When phone call hangs up music should continue (if music was playing before call).

So… can I save playing context and pause music from a scene? Then pop context on phone hangup? Or do I have to save the state in some other variable?

[quote=“hek, post:721, topic:169644”]A also have a scenario where I want to pause eventual music playing (“save play context”) when someone is calling our house. Then the sonos should say who is calling (and keep music paused). When phone call hangs up music should continue (if music was playing before call).

So… can I save playing context and pause music from a scene? Then pop context on phone hangup? Or do I have to save the state in some other variable?[/quote]

Use SavePlaybackContext and RestorePlaybackContext callbacks. And stop the playback just before calling the Say callback to avoid playing your music again just after the message (due to the internal save/restore context integrated in the Say callback).
So you scenario would be. When someone is calling, you have a scene doing that:

  • SavePlaybackContext
  • Stop
  • Say
    When you hang up, there is another scene doing that:
  • RestorePlaybackContext
    Note that it is not really a “pause”.

Great. Thanks @lolodomo.

(Some ranting… My good… To write plugins you really have to be a detective… all these configurationfiles and undocumented stuff…)

I have added the automatic computation of the duration.
As a consequence, the duration argument has been suppressed.

Note that doing my tests, I was forced to add 7 seconds because the time required by the Sonos to start the stream is very long ! I tested with very short and less short sentences in english and french.
Give us your feedback.

Note for guessed: I was constrained to suppress the “&” at the end of the wget command. Bye bye, now I disappear ;D ;D

I have suppressed in the trunk the code that is now unused in file I_Sonos1.xml.

Here is an update of what remains to be improved or done (in my opinion) is:
1 - load/play a radio through TuneIn to get information and radio logo
2 - Say callback (stop the playback and restore the previous context)

3 - add high level callbacks or additional parameters to help management of the Sonos (internal) queue
4 - management of group

I have now added a kind of volume management in the Player tab.

[quote=“hek, post:721, topic:169644”]A also have a scenario where I want to pause eventual music playing (“save play context”) when someone is calling our house. Then the sonos should say who is calling (and keep music paused). When phone call hangs up music should continue (if music was playing before call).

So… can I save playing context and pause music from a scene? Then pop context on phone hangup? Or do I have to save the state in some other variable?[/quote]

Hi, Are you able to share how you’ve got Sonos to work with your phone ? It Sounds a very interesting set up, i’m a huge fan of integrating things with this TTs & Sonos plugin

Maybe raise a new seperate post in the main Sonos Plugin child board for this, as I think people will be really interested to see how people are using this new plugin, as the guys have worked so hard on developing something very special.

Oups, tuning will be required for IE9 because buttons are bigger than with Firefox.

[quote=“parkerc, post:728, topic:169644”]Hi, Are you able to share how you’ve got Sonos to work with your phone ? It Sounds a very interesting set up, i’m a huge fan of the integrating things with TTS and my Sonos.

Maybe raise a new seperate post in the main Sonos Plugin child board for this, as I think people will be really interested to see how people are using this new plugin, as the guys have worked so hard on developing something very special.[/quote]

I have a Fritz!Box. And use my freshly written (finished this evening) plugin to trigger scene on incoming call.

http://forum.micasaverde.com/index.php/topic,12719.0.html

Still have to implement Swedish number->name lookup using some fancy webservice or screenscraping mechanism. But this is rather country specific so I will probably not incorporate it into Fritz plugin.

Hi @Hek,

Thanks for the link, i have FreePBX at home (which has a TTS Google addon) and i’d love to integrate that with Vera/Sonos etc. (but sadly I do not have the skills to do it)

i’'ll take my follow up questions over to your dedicated thread.

Oddly enough 7 seconds is really too long for me :wink:

If we find that we need the concurrency offered by backgrounding, we can always convert over to a local-loop over io.popen calls, with a “default length” calculation at the beginning, and a recompute at the end of the popen loop.

No biggie, and doesn’t look like it’s needed for now.

If we wanted to get really fancy, we could “cache” the last thing we said, since we’ve already requested it and it’s in the FS. That would cutout the call altogether in these cases… just not sure how practical it is in the real world.

[quote=“lolodomo, post:726, topic:169644”]Here is an update of what remains to be improved or done (in my opinion) is:
1 - load/play a radio through TuneIn to get information and radio logo
2 - Say callback (stop the playback and restore the previous context)

3 - add high level callbacks or additional parameters to help management of the Sonos (internal) queue
4 - management of group[/quote]
Right now we have no eventList section to the JSON, so there’s nothing that the Sonos can do to initiate an event that Vera might respond to.

I will take a look over the weekend at adding Events for Play/Pause/Stop. This will give us a starter.

I use the Sonos as an Alarm clock, and “play” a radio station each morning. I’ll use the above to have that Alarm do other things as well (like turn on the Hot water pump) since it’s easier to specify the Alarm though the Sonos’s UI.

… and I’ll obsolete all of the Service variables with [tt]urn:schemas-micasaverde-com:device:avmisc:1[/tt] in them, and write a one-page Wiki set that shows all the Variables we do have…

That should give people enough warning about the legacy ones going away…

I may need you to augment that list with some details as to the intent for the non-standard ones that have been added, and if any of those should be “relied upon” (or are just internal Plugin state management)

Oddly enough 7 seconds is really too long for me ;-)[/quote]

7 seconds is the minimum time for the Sonos to start the playback of the file. I have not checked but I suppose it is done in background.
The files to download from Google are not very big and so the download time is very short. When I select a radio, it does not take so much time to start. I don’t really understand.

No problem.

I’ve looked at the packets a bunch this morning, and have a theory as to why the Say call delays for soo long prior to speaking.

Looking over the raw TCP data, you can see that once the request to retrieve the URL (x-rincon-mp3radio://:80/Say.nnn.mp3) has been made upon the Sonos, it instantly turns that around into a call to the Vera unit to get the content… and the content is returned.

The delays here, for the initial connections, are ~5-10ms (tops) as far as I can see, and it only takes a few ms to download the content.

This is where it gets interesting.

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.

Timing wise, this [roughly] lines up.

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.

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)

[quote=“lolodomo, post:735, topic:169644”]7 seconds is the minimum time for the Sonos to start the playback of the file. I have not checked but I suppose it is done in background.
The files to download from Google are not very big and so the download time is very short. When I select a radio, it does not take so much time to start. I don’t really understand.[/quote]

I’ve formally obsoleted the following older, non-standard ServiceId’s:

  • urn:schemas-micasaverde-com:device:avmisc:1, CurrentZoneName
  • urn:schemas-micasaverde-com:device:avmisc:1, CurrentTransportState
  • urn:schemas-micasaverde-com:device:avmisc:1, PlayMode
  • urn:schemas-micasaverde-com:device:avmisc:1, TrackURI
  • urn:schemas-micasaverde-com:device:avmisc:1, CurrentMute
  • urn:schemas-micasaverde-com:device:avmisc:1, CurrentVolume

These all have counterparts in the standard UPnP namespace.

eg. * urn:upnp-org:serviceId:RenderingControl , Volume

Users with existing deployments will continue to see the variables, but their values will no longer change. Any Scenes, or Lua code, that depends upon the legacy values will need to be changed.

I’ve updated the Wiki page with a stub reference of this information as well.

[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.

CurrentService: name of the current Sonos service (TuneIn, AUPEO!, …)

SonosServicesKeys (not SonosServiceKeys)
for plugin internal usage. It is required to save the data to not loose it after a lua engine reboot.

SonosDevices
Sonos network topology for plugin internal usage. A state variable is required because I need this information in the Javascript tab.

SonosID
It is a state variable that we could suppress and replace by a local variable. And the call to DeviceProperties.GetZoneInfo in the 15s loop to get this data is certainly not required as it is not a data that will change (it is relative to the MAC address of the Sonos unit). We just need to get it a first time, not necessarly at the plugin startup as the Sonos could be not connected.

Icon
a variable that has the value: x-rincon-roomicon:den
I am not sure what is the interest to have this variable and what we could do with it ?

To be continued…

@guessed, I realize I have done something stupid in refreshVolumeNow and refreshMuteNow, I mean calling DeviceProperties.GetZoneAttributes to check comm failure. We could directly call respectively Rendering.GetVolume and Rendering.GetMute and check the return status ? It will avoid a UPnP call.