TTS Madlibs (Vera Alerts / Sonos "Say") (HOWTO)

Standard announcements can get boring…

“There is a visitor approaching”
“Someone has rung the doorbell”

I’m not savvy enough to figure out how to create the code to choose from a list of synonyms for common nouns and verbs and have the TTS code randomly choose from the list of nouns and verbs respectively;

For example

Noun = Visitor
Synonyms = Guest, Visitant, Monster, Secret Service Agent, batman, etc…

Verb = Approaching
sysnonyms = "Coming right for us!, Drawing near, hopping down the bunny trail

So my boring announcement of
“There is a Visitor Approaching”

Could now end up saying

“There is a Monster drawing near”
or
“There is a batman hopping down the bunny trail”.

Those examples may be a bit senseless but I think it would liven things up a bit because after a while, the same announcements can just become “noise”.

Here is the current code I use to send the alert;

luup.call_action(“urn:richardgreen:serviceId:VeraAlert1”, “SendAlert”,
{Message = “{tone:2} A visitor has rung the doorbell.”, Recipients = “”}, 397)

If someone is willing to template how to achieve this I would gladly do the heavy lifting.

Thanks in advance!

I understand that it’s not exactly the same as what you’re proposing but have you seen my thread on dealing with the boredom associated with repetitive messages?

http://forum.micasaverde.com/index.php/topic,13224.msg98253.html#msg98253

OK, here is the solution ;D

The example of code at the bottom is a completely random script of text that calls functions from other devices, and also randomly selects chosen text. I am using this because if you are like me and need help putting stuff together, this should cover a lot of bases, and (most importantly to this thread) show you how to randomize phrases in your script.

here are the nuts and bolts of setting up the phrases and calling them randomly into a variable

Disclaimer: IF THERE IS A BETTER WAY TO SCRIPT THIS PLEASE REPLY. I’M TOTALLY NEW TO THIS

Basic

function GetRandomElement(a)
    return a[math.random(#a)]
end
Greetings = {
    "Hello",
    "Whatup",
    "Top of the Mornin to ya",
    "Listen up",
    -- ...
}
Persons = {
    "Strange looking person",
    "Monster",
    "Bizarre creature",
    "Door to door salesman",
    -- ...
}
local Hello = GetRandomElement(Greetings)
local Person = GetRandomElement(Persons)

EXAMPLE of Random Text and Variables using the Vera Alerts plugin (be sure to replace device IDs)
Props to Signal15 for the Weather code btw.

function GetRandomElement(a)
    return a[math.random(#a)]
end
Greetings = {
    "Hello",
    "Whatup",
    "Top of the Mornin to ya",
    "Listen up",
    -- ...
}
Persons = {
    "Strange looking person",
    "Monster",
    "Bizarre creature",
    "Door to door salesman",
    -- ...
}local currentTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", 333)
local lowTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", 334)
local highTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", 335)
local currentCondition = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1", "Condition", 332)
local currentWind = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1", "WindCondition", 332)
local Hello = GetRandomElement(Greetings)
local Person = GetRandomElement(Persons)
local speakMessage = "{tone:1} " .. Hello .. ".  There is a " .. Person .. " approaching.  Current conditions are " .. currentCondition .. ".  The temperature is " .. currentTemp .. " degrees with a high today of " .. highTemp .. " and a low of " .. lowTemp


luup.call_action("urn:richardgreen:serviceId:VeraAlert1", "SendAlert", 
                  {Message = speakMessage, Recipients = ""}, 397)

Instead of replacing words you can replace entire greetings. . Try this

function GetRandomElement(a)
    return a[math.random(#a)]
end
Greetings = {
    "Hello there bla bla bla",
    "Oh shxt not you again", -- by request ;)
    "Greeting number 3",
    "Listen up bla bla bla",
    " ", -- nothing
    -- ...

}
 
local Hello = GetRandomElement(Greetings)
local speakMessage = "{tone:1} " .. Hello .. "." -- Period Required for LUA to work i guess.


luup.call_action("urn:richardgreen:serviceId:VeraAlert1", "SendAlert", 
                  {Message = speakMessage, Recipients = ""}, 397)

Maybe move the {tone:1} to the phrases area to call another alert sound. …

I simply copied and pasted the above code into the LUUP Event box for the triger of a scene and replaced 397 with my veralerts id and I get error for lua in scenes and events. Any ideas?

I did that from my cell phone last night :wink: Let me test it for you.

UPDATE:
Code above works now. Have fun!

Yep. That seems to be working. I have it set to run when I turn on a light in an infrequently used room in my house and so far so good. I’ll give it a couple more days of testing before I change my other scenes over.

Thanks!

You’re welcome, glad I can finally contribute from a coding standpoint :slight_smile:

How would I go about making this script distinguish between day and night? I’d like to have some things only said at night and some during the day.

Also is there a way to make it not repeat for a certain amount of time? On occasion I will enter the house, then leave, realize I forgot something and go back in. Then the house is stupid when it asks me how my time away was.

Well, I tried to toss

if ( luup.is_night() ) then return true else return false end

in front of my script and it doesn’t work. I also tried putting it in the luup tab hoping it would inhibit the entire scene, but alas none of it works.

Any pointers?

I think there was another way to use the is night call. … search the forums for that and you should find the answer… I feel like the code went after the true statement and the “else” was at the bottom. … sorry for the vagueness. Not in front of a computer to search easily. Let us know

After using this code for a while It became obvious that the place holder intended to randomly generate no notification wasn’t silent. Instead it said “dot”. O I removed the . from this portion of the code:

local speakMessage = "{tone:1} " .. Hello .. "." -- Period Required for LUA to work i guess.

It still works fine and now I don’t get the house saying “dot” to me occasionally when I enter the house.

What was the purpose of having it there any way?

On the is_night code - you can just do this:

return luup.is_night() -- if it's day time, we're done

@a-lurker

Yes but the issue was incorporating that with the existing code.

[quote=“S-F, post:247, topic:172785”]What do you mean by “splitting the phrase”?

Maybe we should take this to the thread I linked to earlier so we can keep this kind of thing all in one place?[/quote]
S-F. What I mean with splitting is exactly what you are doing. Having part 1, 2 and three to make a lot more combinations, this is excelent. I have alread implemented it. It is spanish, sorry, but you can get the idea.

[code]local saludos = { "Hola se?ora, ", "Se?ora, ", "Esposa del se?or, ", "Se?ora amada por su marido, ", "Se?ora Daniela, ", "Estimada Se?ora, ", "Apreciable esposa del se?or, ", "Hermosa mujer, ", "Bella dama, ", "Linda se?ora, ", "Esposa perfecta, ", "Linda mujer, " }
local saludo = saludos[math.random(table.getn(saludos))], “RAID”

local mensajes = { "su casa le desa ?xito! ", "su casa le desea lo mejor! ", "la espero pronto! ", "su casa le desea el mejor de los d?as! ", "tenga un buen d?a! ", "por favor ande con cuidado! ", "es un gusto haberla tenido aqu? en su casa, por favor regrese pronto! ", "vuelva pronto! ", "recuerde siempre cuanto la ama su marido! ", "que tenga suerte en su dia! ", "?xito en su dia! ", "le deseo un dia especialmente bueno! " }
local mensaje = mensajes[math.random(table.getn(mensajes))], “RAID”

local despedidas = { “Hasta luego!”, “Adi?s!” }
local despedida = despedidas[math.random(table.getn(despedidas))], “RAID”

local frase = saludo … mensaje … despedida

luup.call_action(“urn:richardgreen:serviceId:VeraAlert1”, “SendAlert”, {Message = “{tone:tts}” … frase, Recipients = “fudan”}, 23)

return true[/code]

And about distinguishing between day and night that is previously asked by you, it can be easily accomplished with an if … else statement.

At last, in order for you to don’t have a repetitive message if you forgot something, you can do this if you trigger this scene from PLEG and in there, put the condition.

This is probably just limitations set by me not understanding Spanish or the code in any way whatsoever but I’m not entirely clear on what’s happening there. Let’s see if I’ve got this straight. SO what you’re doing is setting up some interchangeable pieces of a sentence and having Vera put them together to create new and interesting phrases?

That is correct, let me explain you the variables’ meaning:

saludos ← options for part 1 of the phrase.
saludo ← the selected test for part 1.

mensajes ← options for part 2 of the phrase.
mensaje ← the selected test for part 2.

despedidas ← options for part 3 of the phrase.
despedida ← the selected test for part 3.

frase ← the mix of selected part 1 with selected part 2 and selected part 3.

If it is not clear enought, feel free to ask.

Hi

Great job…

Currently it looks to be Vera Alert focused, would you be able to create an example script for the Sonos that people to use?

If possible it would be great to add it to the Sonos Dynamic Messages thread here-> http://forum.micasaverde.com/index.php/topic,12408.0.html

[quote=“parkerc, post:18, topic:174535”]Hi

Great job…

Currently it looks to be Vera Alert focused, would you be able to create an example script for the Sonos that people to use?

If possible it would be great to add it to the Sonos Dynamic Messages thread here-> http://forum.micasaverde.com/index.php/topic,12408.0.html[/quote]

parkerc, I don’t use sonos, but it is exactly the same for anything, once you have the variable with the phrase formed, you just substitute it in the code you alread have. Eg.

[code]url = require(“socket.url”)
local saludos = { "Hola se?ora, ", "Se?ora, ", "Esposa del se?or, ", "Se?ora amada por su marido, ", "Se?ora Daniela, ", "Estimada Se?ora, ", "Apreciable esposa del se?or, ", "Hermosa mujer, ", "Bella dama, ", "Linda se?ora, ", "Esposa perfecta, ", "Linda mujer, " }
local saludo = saludos[math.random(table.getn(saludos))], “RAID”

local mensajes = { "su casa le desa ?xito! ", "su casa le desea lo mejor! ", "la espero pronto! ", "su casa le desea el mejor de los d?as! ", "tenga un buen d?a! ", "por favor ande con cuidado! ", "es un gusto haberla tenido aqu? en su casa, por favor regrese pronto! ", "vuelva pronto! ", "recuerde siempre cuanto la ama su marido! ", "que tenga suerte en su dia! ", "?xito en su dia! ", "le deseo un dia especialmente bueno! " }
local mensaje = mensajes[math.random(table.getn(mensajes))], “RAID”

local despedidas = { “Hasta luego!”, “Adi?s!” }
local despedida = despedidas[math.random(table.getn(despedidas))], “RAID”

local frase = saludo … mensaje … despedida

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(frase)}, AV_DEV)[/code]