Text To Speech (TTS) With Sonos - Creating Dynamic Messages

Should be something like this:

[code]url = require(“socket.url”)
local AV_DEV = 452
local LS_SID = “urn:micasaverde-com:serviceId:Sonos1”

local_hours = os.date(‘%I: o clock’)
local_hours = local_hours:gsub(“^0”, “”)
local_minutes = os.date(‘%M minutes’)
local_minutes = local_minutes:gsub(“^0”, “”)

luup.call_action(LS_SID, “Say”, {Text = string.format(“The time is %s past %s”, local_minutes, local_hours),Volume=60}, AV_DEV)

[/code]

You probably should add the logical test to account for the exact hours e.g:

[code]url = require(“socket.url”)
local AV_DEV = 452
local LS_SID = “urn:micasaverde-com:serviceId:Sonos1”
local time = os.date(‘%M minutes’)

local_hours = os.date(‘%I: o clock’)
local_hours = local_hours:gsub(“^0”, “”)
local_minutes = os.date(‘%M minutes’)
local_minutes = local_minutes:gsub(“^0”, “”)

if local_minutes < “1” then
luup.call_action(LS_SID, “Say”, {Text = string.format(“The time is %s”, local_hours),Volume=40}, AV_DEV)

else 
luup.call_action(LS_SID, "Say", {Text = string.format("The time is %s  past %s", local_minutes, local_hours),Volume=60}, AV_DEV)

end[/code]

That worked perfectly! way out of my league!

I combined that with the time code… and it all works. One weird thing though. the volume is significantly louder for the time part, vs the weather announcement. all in the same Lua code. Here’s how i combined them.

[code]url = require(“socket.url”)
local AV_DEV = 45
local LS_SID = “urn:micasaverde-com:serviceId:Sonos1”

local time = os.date(‘%M minutes’)
local_hours = os.date(‘%I: o clock’)
local_hours = local_hours:gsub(“^0”, “”)
local_minutes = os.date(‘%M minutes’)
local_minutes = local_minutes:gsub(“^0”, “”)

local TEMP_SID = “urn:upnp-org:serviceId:TemperatureSensor1”
local TEMP_DEV = luup.variable_get(TEMP_SID, “CurrentTemperature”, 196)

luup.call_action(LS_SID, “Say”, {Text = string.format(“Welcome home. The current temperature in the house is %s degrees”, TEMP_DEV )}, AV_DEV)

if local_minutes < “1” then
luup.call_action(LS_SID, “Say”, {Text = string.format(“The time is %s”, local_hours),Volume=40}, AV_DEV)
else
luup.call_action(LS_SID, “Say”, {Text = string.format(“The time is %s past %s”, local_minutes, local_hours),Volume=60}, AV_DEV)
end
[/code]

The reason behind the differ volume was the time string includes the declared volume.

You could include the volume in the temp of combine them e.g

if local_minutes < “1” then
luup.call_action(LS_SID, “Say”, {Text = string.format(“Welcome home. The current temperature in the house is %s degree and the time is currently %s”, , local_hours),Volume=40}, AV_DEV)
else
luup.call_action(LS_SID, “Say”, {Text = string.format(“Welcome home. The current temperature in the house is %s degree and the time is %s past %s”,TEMP_DEV, local_minutes, local_hours),Volume=60}, AV_DEV)
end

I see the second string the volume is set at “60” whereby, if it was on the hour as in the first string, the volume is set to “40”

perfect… thanks. I’m not sure where the weather statement was getting the volume setting from, but combining them fixed it perfectly, saved for the extra comma :slight_smile:

awesome.

The original weather would have been at the last volume the Sonos was at.

That makes sense. Thanks for the help!

I’ve been using this code and it works great and just want to say what a great forum this is - everyone is really helpful.
So…in that light, I would like to add another piece of logic to the below that checks only “armed” sensors. I’m also kinda of new to the LUUP code so any help would be greatly appreciated!

I figured it out… :slight_smile:

[quote=“Borat, post:110, topic:173177”]Sure here you go:

– Door/Window sensor check and speech annotation by Pasqual Zottola
local vol = 60
local son = 23
local devcnt = 0
local devno = 0
local numopen = 0
local isare = “is”
local opensensors = " "
luup.log(‘Commencing sensor device search loop’)
for deviceNo,d in pairs(luup.devices) do
if d.category_num == 4 and d.subcategory_num == 1 and d.armed == 1 then

  local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", deviceNo) or "Nil"
 
  if (tripped == "1") then
     opensensors = opensensors .. ". " .. d.description .. ","
     numopen = numopen + 1
  end

luup.log(d.description … ’ status:’ … tripped … ’ Dev #’ … deviceNo … ’ id:’ … d.id … ’ cat #:’ … d.category_num … ’ type:’ … d.device_type)
devcnt = devcnt + 1
end
end
if numopen == 0 then --If there are no sensors tripped, log and announce!
luup.log(‘There were ’ … devcnt … ’ door and window sensors found and all are closed’)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text=devcnt … " sensors were checked, and all are closed. House is secure. Goodbye!", Language=“en”, Volume=vol}, son)

else --If there are any sensors tripped, log and announce!
if numopen > 1 then
isare = “are”
end
luup.log(‘There were ’ … devcnt … ’ door and window sensors found and ’ … numopen … " " … isare … ’ open’ … opensensors)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text=“Warning! House may not be secure,” … devcnt … " sensors were checked and " … numopen … " " … isare … " open. Check," … opensensors, Language=“en”, GroupDevices=“32”, Volume=vol}, son)

end[/quote]

wow, nice plugin, just got the sonos 1 and tts works nice

Also modified the below to send a vera alert notification in case any sensors are found open:

– Door/Window sensor check and speech annotation by Pasqual Zottola
local vol = 10
local vol1 = 45
local son = 40
local devcnt = 0
local devno = 0
local numopen = 0
local isare = “is”
local opensensors = " "
luup.log(‘Commencing sensor device search loop’)
for deviceNo,d in pairs(luup.devices) do
if d.category_num == 4 and d.subcategory_num == 3 then

  local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", deviceNo) or "Nil"
 local armed = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Armed", deviceNo) or "Nil"
  if (tripped == "1" and armed == "1") then
     opensensors = opensensors .. ". " .. d.description .. ","
     numopen = numopen + 1
  end

luup.log(d.description … ’ status:’ … tripped … ’ Dev #’ … deviceNo … ’ id:’ … d.id … ’ cat #:’ … d.category_num … ’ type:’ … d.device_type)
devcnt = devcnt + 1
end
end
if numopen == 0 then --If there are no sensors tripped, log and announce!
luup.log(‘There were ’ … devcnt … ’ door and window sensors found and all are closed’)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text=devcnt … " sensors checked, House is secure.", Language=“en”, Volume=vol, GroupZones=“Current”}, son)

else --If there are any sensors tripped, log and announce!
if numopen > 1 then
isare = “are”
end
luup.log(‘There were ’ … devcnt … ’ door and window sensors found and ’ … numopen … " " … isare … ’ open’ … opensensors)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text=“Warning! House may not be secure,” … devcnt … " sensors were checked and " … numopen … " " … isare … " open. Check," … opensensors, Language=“en”, GroupDevices=“32”, Volume=vol1}, son)
luup.call_action(“urn:richardgreen:serviceId:VeraAlert1”, “SendAlert”, {Message = “{tone:1} One of the doors are open, need to check”, Recipient = “Davids_Phone”},21)

end

[quote=“becky, post:172, topic:173177”]I’d be happy to! Below are the lines that are specific to the calendar device. Make sure you have installed the Gcal3 device and the sonos device first. You have to do a little searching on the forum, but are excellent plugins and have really great documentation!! (kudos to the developers) You’ll need to change my device numbers to reflect your own.

My code is a little sloppy, but it seems to work for us.
variable and device mumbo-jumbo:

url = require(“socket.url”)
local AV_DEV = 48
local LS_SID = “urn:micasaverde-com:serviceId:Sonos1”
local time = os.date(‘%I:%M’)
local todaydate = os.date(‘%Y-%m-%d’)
local SONOSZONES=“ALL”
local SameVolume=“true”
local TEMP_SID =“urn:upnp-org:serviceId:TemperatureSensor1”
local WUGTempHigh = luup.variable_get(TEMP_SID, “CurrentTemperature”, 33)
local currentCondition = luup.variable_get(“urn:upnp-micasaverde-com:serviceId:Weather1”, “Forecast.1.Condition”, 30)
local GS_SID = “urn:srs-com:serviceId:GCalIII”
local jsonEvents = luup.variable_get(GS_SID, “gc_jsonEvents”,52)

checking to see if there are any events for the day. if not, tell us that there are no events for today.

if ((jsonEvents == “[]”) or (jsonEvents == nil)) then
TodaysEvents=“There are no events for today.”
else
TodaysEvents="Todays events are "
end

unwrapping all the different variables in the device variable.

[b]package.loaded.json = nil
local json = require(“json”)
local eventList =json.decode(jsonEvents)
local numberEvents = table.getn(eventList)
local startevent, startDate, startTime, endevent, endTime, eventname, event

looping around the dumping the variables into an array

for i = 1,numberEvents do
startevent = eventList[ i ].eventStart
startDate = os.date(“%Y-%m-%d”, startevent)
startTime = os.date(“%H:%M:%S”, startevent)
endevent = eventList[ i ].eventEnd
endTime = os.date(“%H:%M:%S”, endevent)
eventname = eventList[ i ].eventName

if the event happens today, add it to the TodaysEvents variable. if not, don’t add it.

if (startDate == todaydate) then
TodaysEvents = TodaysEvents … eventname … " . "
luup.log(event)
end[/b]

end
package.loaded.json = nil

and then of course sending it all to the sonos device.

luup.call_action(LS_SID, “Say”, {Text = string.format(“Good morning, Kirkwoods! It is now %s. Here is your daily morning report. Today will be %s with a high of %s degrees. %s. Have a great day.”, time, currentCondition, WUGTempHigh, TodaysEvents), GroupZones=SONOSZONES, SameVolumeForAll=SameVolume, Volume=50}, AV_DEV)[/quote]

Becky, This look great, however Newbie question, how does one make this work if you would be so kind and provide a short tutorial would be greatly appreciated. Mike

@dp0100, I have the SONOs and TTS installed and working well, question as I review this thread how is the various code snip-its used. I know if I create a scene I can insert Luup within but some of these items almost look like they are more than a simple scene or am I missing something? for example the “Tell Time” if it were a scene needs some how to trigger on the hour, quarterly which I do not see that possible any clues would be greatly appreciated, Mike

Hi Mike,

The example I referenced is just a scene - I created a new scene called = Security System Check. Then configured the schedule section to run every night at 9:30pm. Then go to the LUUP page and pasted that code (of course making sure the id’s match your specific configurations) BTW: I’m on UI5

So for your “Tell Time” example, I would do the exact same thing, in the schedule have it setup to run every hour or what ever your time constraint is. ( though not sure I would do it every hour) Hope this helps…David

David,
Thanxs for the comeback. I created a scene using “schedule” as the trigger and set it 1 hour and dropped the luup code within the LUUP page. Was able to test the scene by depressing the scene play button which worked like a champ with one exception the 1 hour is set to when ever I created the scene “10:08” so then next trigger is set for 11:08 any suggestions as to how one could set the timer to actual clock time? Mike

Sure, np…
I’m sure there is a much easier way via LUUP but I’m kinda of new to this so I’ll use the trigger/schedule functionality.
Create a new scene that is scheduled to start every morning at a predetermined time (say 8am). Then update your existing scene to trigger off of this new one that launches every morning at 8am.
If you need to end it at another time, just create a new scene that triggers at say 9pm and terminates your scene that occurs every hour. Make sense?

David,
Makes sense, I will make the update in my scene to reflect. I’m also starting to use PLEG and will experiment with it to do the same. Mike

There was a software update for Sonos today and now the “Say” function does not work anymore. I get an error on the Sonos that says : Unable to play “Say.***.mp3”- file is encoded incorrectly". My Sonos has been playing the same mp3 files on a daily basis flawlessly for many many months without any issues. Is there a cure for what ails my Sonos?

Sorry, but I made a mistake and asked this question in the wrong forum.

Sonos with Tts don’t work now.
Have anyone this problem or it’s only my ?