Author Topic: Text To Speech (TTS) With Sonos - Creating Dynamic Messages  (Read 81498 times)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« on: November 05, 2012, 04:42:06 pm »
Hi,

As i was keen to give me Veralite the image of some verbal intelligence @Guessed helped me with an earlier version of the Sonos Plugin to create some dynamic speech (See here http://forum.micasaverde.com/index.php/topic,11269.0.html)

I'm going to update this first section with any new dynamic 'say' commands i've pulled together.

The Talking Sonos Clock
http://forum.micasaverde.com/index.php/topic,12408.msg90986.html#msg90986

Period Of The Day Welcome
http://forum.micasaverde.com/index.php/topic,12408.msg92210.html#msg92210

Check The Status Of The Lights
http://forum.micasaverde.com/index.php/topic,12408.msg92209.html#msg92209

Random Words
http://forum.micasaverde.com/index.php/topic,12408.msg159478.html#msg159478

Simon Says Game
http://forum.micasaverde.com/index.php/topic,12408.msg161152.html#msg161152

All Zones Message
http://forum.micasaverde.com/index.php/topic,12408.msg159525.html#msg159525

---ooo000ooo---

What's The Temperature ?

This was my first one and testing it again, it still works, and it's great how Google & Sonos can tell me the temperatures of my kids rooms now..

Code: [Select]
url = require("socket.url")

local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"
local MN_SID = "urn:micasaverde-com:serviceId:MediaNavigation1"

local TEMP_SID = "urn:upnp-org:serviceId:TemperatureSensor1"
local benTemp = luup.variable_get(TEMP_SID,"CurrentTemperature", 42)
local emmaTemp = luup.variable_get(TEMP_SID,"CurrentTemperature", 48)
local lang = "en"
local speak = url.escape(string.format("Ben's Room is currently at %s degrees, and emmers is at %s ", benTemp, emmaTemp))

luup.call_action(LS_SID, "SetURIToPlay", {URIToPlay = string.format("x-rincon-mp3radio://translate.google.com/translate_tts?tl=%s&q=%s", lang, speak)},AV_DEV)
luup.call_action(MN_SID, "Play", {},AV_DEV)

Feel free to evolve this script and share any examples you might create here for others to use.
« Last Edit: May 05, 2014, 02:53:23 pm by parkerc »

Offline guessed

  • Master Member
  • *******
  • Posts: 5293
  • Karma: +90/-22
  • Release compat is not a bolted-on afterthought
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #1 on: November 05, 2012, 05:57:14 pm »
You might want to try the "Say" action, of the Sonos1 SID, directly.  It'll handle building the URL, the appropriate URL value encoding, and the "Play" action all internally.  You'll just need to tell it to stop, since it will play in a loop...

The last 3 lines will be replaced with something akin to:

Code: [Select]
luup.call_action(LS_SID, "Say",
                 {Text = string.format("Ben's Room is currently at %s degrees, and emmers is at %s ", benTemp, emmaTemp)},
                 AV_DEV)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #2 on: November 06, 2012, 03:25:26 am »
Thanks @Guessed

Very Nice ! (And much less cluttered now..)

Code: [Select]
url = require("socket.url")

local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"

local TEMP_SID = "urn:upnp-org:serviceId:TemperatureSensor1"
local benTemp = luup.variable_get(TEMP_SID,"CurrentTemperature", 42)
local emmaTemp = luup.variable_get(TEMP_SID,"CurrentTemperature", 48)

luup.call_action(LS_SID, "Say", {Text = string.format("Ben's Room is currently at %s degrees, and Emmers is at %s ", benTemp, emmaTemp)}, AV_DEV)

@Guessed I've had a quick go at getting dates, but I only can get the unix ones. To help build dynamic message, shoul someone want their Songle* to "say" that a particular device was "last updated on 6th of November", are you aware of anything that could convert the unix clock to words and not numerical values that could then be spoken?

A search gave me this, but it's not something I can work out. http://forum.micasaverde.com/index.php/topic,5381.msg30660.html#msg30660

Also to do this I assume I would need to create some kind of conversion table etc. e.g 4 = April?

* = I'm testing out names for the Sonos/Google TTS set up  ;)

UPDATE

I found this online - which seems interesting - http://lua-users.org/wiki/DateFormattingFunctions
« Last Edit: November 06, 2012, 04:24:44 am by parkerc »

Offline guessed

  • Master Member
  • *******
  • Posts: 5293
  • Karma: +90/-22
  • Release compat is not a bolted-on afterthought
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #3 on: November 06, 2012, 08:32:05 am »
For the first one, Lua's os.date accepts a string based format "pattern" that is used to convert the number into something of your choice.

A more complete list of the format elements can be found in pages like:
    http://linux.about.com/od/commands/l/blcmdl1_date.htm

You'd have to test to see which ones are really available.
« Last Edit: November 06, 2012, 02:55:39 pm by guessed »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #4 on: November 06, 2012, 06:13:01 pm »
Thanks to Guessed for the os.date link, and now here's another TTS to share. This one is called..

'The Talking Sonos Clock' ;)

Code: [Select]
url = require("socket.url")

local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"

local TEMP_SID = "urn:upnp-org:serviceId:TemperatureSensor1"
local time = os.date('%M minutes past %I:')

luup.call_action(LS_SID, "Say", {Text = string.format("The time is currently %s", time)}, AV_DEV)

More to follow.
« Last Edit: November 06, 2012, 06:19:05 pm by parkerc »

Offline guessed

  • Master Member
  • *******
  • Posts: 5293
  • Karma: +90/-22
  • Release compat is not a bolted-on afterthought
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #5 on: November 06, 2012, 06:34:37 pm »
Now that you're using the built-in Say action, you can strip out the need for the "require" call at the top (it's effectively inside the Sonos implementation)

For the use-case of the talking clock, you can also strip out the temperature declarations, so it'll get even smaller.

All in all, it gets to be fairly small:

Code: [Select]
local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"
local time = os.date('%M minutes past %I:')

luup.call_action(LS_SID, "Say", {Text = string.format("The time is currently %s", time)}, AV_DEV)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #6 on: November 07, 2012, 02:45:39 pm »
Thanks @guessed, that's what happens when you do things late at night, I missed the obvious ;)

My next challenge is to try and create a script that will carry out a series of checks on something, and then report back on it's findings. This way the resulting TTS could potentially be a different message depending on the results.

Sonos Status Reporting

For example

i)  Check all temperature sensors are over 20c

If they are then say "all sensors are reporting 20c or above" but if they're not, then say "not all sensors are reporting 20c or above". - it might even be possible for me to get it to say which one is not so it's more helpful and say "John's Bedroom is reporting 18.5c"

Others could be to

ii) Check all security devices are armed etc ..
iii) Check all lights are off etc..

To save the number of Google TTS requests needed, it might be better to just play an MP3 or WAV file from a NAS when everything is fine and just use the TTS for information/error verbal messages.

As always, all thoughts/ideas/input welcome..
« Last Edit: November 07, 2012, 03:29:54 pm by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #7 on: November 09, 2012, 05:59:54 pm »
Hi

It seems my new found coding skills have come up against a brick wall - I'm trying to check the status of 3 lights and depending on the results it should play a particular message. The logs seem to point to the very first line, I'm sure it's obvious but I just can't see it. :(

Code: [Select]
local LIGHT_ID1= 22
local LIGHT_ID2= 82
local LIGHT_ID3= 44
local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"
local SEC_SERV = "urn:upnp-org:serviceId:SwitchPower1"

local v = local function checkLightsOnOff()

local bedroomlight = luup.variable_get(SEC_SERV, "Status",LIGHT_ID1)
local halllight = luup.variable_get(SEC_SERV, "Status",LIGHT_ID2)
local loungelight = luup.variable_get(SEC_SERV, "Status",LIGHT_ID3)

if(bedroomlight == "0")then
if(halllight == "0")then
if(loungelight == "0")then

luup.log("v is " .. v) 
luup.call_action(LS_SID, "Say", {Text = string.format("All Lights Are Off")}, AV_DEV)

return true

else

luup.call_action(LS_SID, "Say", {Text = string.format("One Or More Lights Are On")}, AV_DEV)

return false

    end
end

Offline oTi@

  • Beta Testers
  • Master Member
  • *****
  • Posts: 4041
  • Karma: +32/-6
  • UI what ?!
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #8 on: November 10, 2012, 09:14:17 am »
For one, there's more if's than end's.

Did you try it for a single light first (i.e. start with fewer code lines), then expand from there?
Dezwaved at the moment...

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #9 on: November 10, 2012, 10:11:05 am »
Hi OTi

Thanks for responding.

Yes I tried it with just the one light and it still failed at the same place , the first line.
I pasted everything in just so people could see the whole thing that I'm trying to do and point out anything else that might be wrong ..

Log shows..

01   11/10/12 15:06:29.897   LuaInterface::LoadCode: [string "local LIGHT_ID1= 22..."]:6: unexpected symbol near 'local' <0x2fadc680>
01   11/10/12 15:06:29.899   JobHandler_LuaUPnP::RunLua failed: local LIGHT_ID1= 22

Offline teonebello

  • Sr. Member
  • ****
  • Posts: 405
  • Karma: +0/-0
  • Macs, Home Automation, Bikers
Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #10 on: November 10, 2012, 10:58:45 am »
If you have two voice command, how can we separate? Luup.sleep?

Any example to avoid long waiting to confirm the execution of a scene?

Thank you
Matteo

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #11 on: November 10, 2012, 02:51:35 pm »
Hi Matteo

My goal was to have Vera check 3 lights in the house, if one or more was on it would 'say' one type of message, but if no lights were on then it should say a different type of message.

I was just looking for it to just run the once, but I guess it could have luup.sleep added so it repeats the check every xxxx seconds?

I'm just not sure what I have done wrong that it seems to fail on the first line, no matter which local value I choose to put there.

If I try a piece of code that I know works, it seems to go through ok..
Which makes this even more strange??

Offline santoal

  • Newbie
  • *
  • Posts: 17
  • Karma: +0/-0
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #12 on: November 15, 2012, 12:37:47 am »
Hi

If music or radio is already playing and I invoke a "say" command, is there a way or resuming whatever was playing?

Offline guessed

  • Master Member
  • *******
  • Posts: 5293
  • Karma: +90/-22
  • Release compat is not a bolted-on afterthought
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #13 on: November 15, 2012, 01:01:03 am »
Its not built in at this time, but its possible to do it if you read back through the main post.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Text To Speech (TTS) With Sonos - Creating Dynamic Messages
« Reply #14 on: November 17, 2012, 05:56:56 pm »
Here you go, finally! Thanks for all the help from the Scene Scripting forum on getting this one to work in the end.

Check The Status Of The Lights

This one will check and tell you if all the lights are off or if one or more are still on.

Code: [Select]
local LI_DEV1 = 82
local LI_DEV2 = 22
local LI_DEV3 = 53
local AV_DEV = 5
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"
local SEC_SERV = "urn:upnp-org:serviceId:SwitchPower1"

local livingroomlight = luup.variable_get(SEC_SERV, "Status",LI_DEV2)
local bedroomlight = luup.variable_get(SEC_SERV, "Status",LI_DEV1)
local halllight = luup.variable_get(SEC_SERV, "Status",LI_DEV3)

if ((livingroomlight == "0") and (bedroomlight == "0") and (halllight == "0")) then
luup.log("All light are off")
luup.call_action(LS_SID, "Say", {Text = string.format("All lights are off ")}, AV_DEV)
else
luup.log("One or more lights is on")
luup.call_action(LS_SID, "Say", {Text = string.format("One or more lights are on ")}, AV_DEV)
end
« Last Edit: November 17, 2012, 06:27:50 pm by parkerc »