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

@kiethr, did you per chance have any success in getting your LUA snippit to work, and if so would you be so kind and share your solution? Mike

[quote=“kiethr, post:215, topic:173177”]Well i changed that line and the code did not fail. However i’m not home so I will have to wait until later to see if it is working.

Thanks for the tip!!![/quote]

@keithr, after taking your updated of @becky’s code, I did a few modifications to finally getting the LUA snippit to work on my VERA - Edge. I’m hoping that @becky was able to get the Weather Alarm(s) to also work. Does anyone know of a way to get the calendar event to also have the start times announced?

[code]
– Morning Announcement (Becky) modified by Michael Blackwell. To let the family know what’s going on for the day before we get out of bed. It includes, current time, current weather condition, current temperature and any calendar events for the day from google calendar via GCal3 plugin plugin
local AV_DEV = 15 – Sonos Device ID within Vera
local LS_SID = “urn:micasaverde-com:serviceId:Sonos1”
local LS_ZONES = “Kitchen,Living Room,Patio Room” – Valid GroupZones = “All”, “Kitchen”, “Patio Room”, “Living Room”, “Master Bedroom”, “Lily’s Cabin” Note: if you are grouping more than one zone, ensure that there are no spaces between the deliminating comma.
local LS_VOLUME = 70
local time = os.date(‘%I:%M’)
local todaydate = os.date(‘%Y-%m-%d’)
local WEATHER_ID = 5 – World Weather Device ID
local WEATHER_ID2 = 6 – World Weather Child Device ID
local WEATHER_SID = “urn:upnp-micasaverde-com:serviceId:Weather1”
local TEMP_SID = “urn:upnp-org:serviceId:TemperatureSensor1”

local WeatherCurrCondition = luup.variable_get(WEATHER_SID, “Condition”, WEATHER_ID)
local WeatherCurrTemp = luup.variable_get(TEMP_SID, “CurrentTemperature”, WEATHER_ID2)

local GS_SID = “urn:srs-com:serviceId:GCalIII”
local jsonEvents = luup.variable_get(GS_SID, “gc_jsonEvents”, 243) --GCal3 Sensor Device ID

– 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 Calendar events scheduled for today. "
else
TodaysEvents=” The Calendar Events for Today are as follows; "
end

– unwrapping all the different variables in the device variable.
local json = require(“dkjson”) – depending on your vera version like Edge or Plus, you may need to use require(“json”)
local eventList =json.decode(jsonEvents)
package.loaded.json = nil
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 (i == 1) then
TodaysEvents = TodaysEvents … eventname … " . "
else
TodaysEvents = TodaysEvents … " then " … eventname … " . "
end
luup.log(event)
end
package.loaded.json = nil

– Establishing proper greeting depending on the time of day
local time2 = os.date(‘It is %H:%M.’)
local hour=tonumber(os.date(‘%H’))
local greeting=“”

if hour < 12 then
greeting = “Good morning”
elseif hour < 17 then
greeting = “Good afternoon”
elseif hour < 21 then
greeting = “Good evening”
else
greeting = “Good evening”
end

– and then of course sending it all to the sonos device to make the announcement.
luup.call_action(LS_SID, “Say”, {Text = string.format(“%s Blackwell family! The time is. %s Here is your daily report. Today’s weather will be %s with a high of %s degrees %s Have a great day.”, greeting, time, WeatherCurrCondition, WeatherCurrTemp, TodaysEvents), GroupZones=LS_ZONES, SameVolumeForAll=“true”, Volume=LS_VOLUME}, AV_DEV)[/code]

Made correction in the Say statement had some flaws…

I’ve noticed that this thread seems to be a little quite aka not much new content (e.g. new techniques, solutions and code) has been added of late, is this due to everything has been previously addressed or are people moving to something other devices? Mike

Do You know how to Say also the Room where is the sensor?

[quote=“pasqualz, post:99, topic:173177”][size=18pt]Door & Window Sensor Check and Annunciation[/size]
Ok, so it took more than “a few hours” but here it is!!! This script checks for all connected door/window sensors, announces how many there are and if any are open (tripped,) it tells you which ones. I need to do more tinkering with the speech strings to make them smoother and maybe a bit slower. I plan to have two scenes, one for upstairs sonos and one for downstairs. The variables should be self explanatory. Feel free to reply with questions, comments, improvements, etc.

– Door/Window sensor check and speech annotation by Pasqual Zottola
local vol = 50
local son = 27 --mast bdr =33, kitch=27
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 then

  local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", deviceNo) or "Nil"
  
  if (tripped == "1") then
     opensensors = opensensors .. ". " .. d.description
     --[[ This line will change to recording info to an array so sonos speaks only once.

luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”,
{Text=d.description … " is Open", Language=“en”, Volume=vol}, son)
–]]
– luup.log(d.description … " status was " … tripped)
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=“There were " … devcnt … " door and window sensors found, and all are closed”, 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=“There were " … devcnt … " sensors found and " … numopen … " " … isare … " open.” … opensensors, Language=“en”, Volume=vol}, son)

end[/quote]

A simple lua script to have Vera announce over Sonos the time, temperature, weather conditions and today?s forecast using DarkSky weather app data. Bummer that WeatherUnderground now requires payment for API key. :-*

DarkSky is a good choice (install via AltUI App Store), with a ton of weather-related variables to pull in. Code snippet attached (yes, it?s a bit sloppy, but functional, would love suggestions/critiques!).

Just replace IDs with your own devices, find a chime/bell sound file you like (optional!) and upload it to /www and then drop the script into a scheduled scene that runs every morning. Easy peasy.

BTW, don?t need second weather device ID, I was just testing if you could pull in data from multiple devices in one script without blowing anything up…

Enjoy,
.//A.

local AV_DEV = XX -- Sonos device ID
local LS_SID = "urn:micasaverde-com:serviceId:Sonos1"
local LS_DURATION = 5 ? length of chime sound
local LS_VOLUME = 35
local LS_PATH = "http://<localVeraIPaddress>/ZenTempleBell.mp3" -- Chime sound file in /www
local time = os.date('%M minutes past %I:')
local name = "Princess Cupcake" ? How you want to be greeted
local WeatherID1 = XX -- Weather app ID ? your DarkSky main device ID
local WeatherID2 = XX -- Weather app ID2 ? your DarkSky Temperature device ID, optional

local WEATHER_SID = "urn:upnp-org:serviceId:TemperatureSensor1"
local WEATHER_CID = "urn:upnp-micasaverde-com:serviceId:Weather1"

    local Today = luup.variable_get(WEATHER_CID, "TodayConditions", WeatherID1)
    local Current = luup.variable_get(WEATHER_CID, "CurrentConditions", WeatherID1)
    local HighTemp = luup.variable_get(WEATHER_CID, "TodayHighTemp", WeatherID1)
    local Precip = luup.variable_get(WEATHER_CID, "PrecipProbability", WeatherID1) 
    local Temp = luup.variable_get(WEATHER_SID, "CurrentTemperature", WeatherID2) 

luup.call_action (LS_SID, "Alert", {URI=LS_PATH , Duration=LS_DURATION , Volume=LS_VOLUME, GroupZones="ALL"}, AV_DEV)

luup.call_action(LS_SID, "Say", {Text = string.format("Good morning %s. You are amazing... The time is currently %s o'clock.   Right now, the weather is %s and the temperature is %s degrees. Today will be %s with a high of %s and a %s percent chance of precipitation... I hope you have a peaceful day.", name,time,Current,Temp,Today,HighTemp,Precip),GroupZones="ALL", SameVolumeForAll="true", Volume=LS_VOLUME}, AV_DEV)

luup.call_action (LS_SID, "Alert", {URI=LS_PATH , Duration=LS_DURATION , Volume=LS_VOLUME, GroupZones="ALL"}, AV_DEV)