Alexa TTS (Text-To-Speech) [and more] plug-in for Vera

This is super! My home now talks to me and talks back to me! So far my implementations are:

  1. Door Open and Close Announcements
  2. Gate Perimeter Announcements (via cctv link)
  3. Door Lock / Unlock and Arming Announcements
  4. Doorbell Repeater / Announcement
  5. Smoke Alarm Repeater / Announcement (for less scandalous than sirens, temp sensor trigger sirens)
  6. Reports Door Status (Closed & Locked, Closed but Unlocked and Opened) with count upon demand
  7. Reports All Room temperatures upon demand
  8. Reports count and which rooms have motion detected upon demand
  9. Reports count and which tv’s are turned on upon demand (via energy consumption of smart plug)
  10. Reports Home Summary (all info in my dashboard) upon demand

If anybody needs any of the luup codes for the above functions, just request and i will post here. The reports are triggered via a voice command routine in alexa that runs a vera scene with the luup code. To omit too much information in the reports, i use if statements to put blanks on irrelevant data such as rooms without motion. To summarize some of the reports, i use if statements to convert status to count such as number of TV’s turned on.

Many thanks again therealdb! my home feels smart and alive now, haha

3 Likes

Oooh 7 would be useful, please!

C

Yes, one of my favourite one, for the summer, is “Alexa, what’s pool’s temperature?”. I can use LastAlexa (not yet implemented here) + TTS to query my temperature sensor and report back:

local temperature = luup.variable_get(D_TEMP, "CurrentTemperature", dev_id)
temperature = tonumber(temperature)
local text = "Pool's temperature is %s. "
replyTTS(string.format(text, temperature))

where replyTTS is my function using the Alexa device you’ve spoken to. I will implement LastAlexa command very soon (it’s dependent on jq as well…), but you can just reply with the default one in the meantime, if you want to start.

I also have global temperature reports, mixed with Alexa’s weather briefing, using a routine that first starts the Alexa’s one, then starts a scena on my Vera. It’s pretty cool once you start integrating it :slight_smile:

2 Likes

@robie

Please share your luup codes I am interested to know more.

Thanks.

Hi Catman,

here’s the luup for #7 - (just change the names based on your preference and the device numbers located at the end of each line based on your setup). The math.floor +0.5 is to round off the temperature value so that it is easy to understand when said by alexa. The text, or “”, at the end of the local line messages should help avoid error messages in case the device is unavailable but i’m not really sure if it works as i only copied it from google searches.

I placed the luup in a scene which is triggered by alexa via routines. So, in alexa routines, it is configured as - When you say “Alexa, temperature”, Alexa will Power On Temperature scene.

local DadMomTemp = math.floor(0.5+luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor1”, “CurrentTemperature”, 179)) or “”
local BoysTemp = math.floor(0.5+luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor1”, “CurrentTemperature”, 67)) or “”
local InaTemp = math.floor(0.5+luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor1”, “CurrentTemperature”, 36)) or “”
local EntTemp = math.floor(0.5+luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor1”, “CurrentTemperature”, 74)) or “”
local DiningTemp = math.floor(0.5+luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor1”, “CurrentTemperature”, 225)) or “”

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text=“The temperature in your Room is " … DadMomTemp … " degrees Celsius. Boys’ Room is " … BoysTemp … " degrees Celsius. Ina’s Room is " … InaTemp … " degrees Celsius. Entertainment Room is " … EntTemp … " degrees Celsius. and Dining Room is " … DiningTemp … " degrees Celsius”, Volume=50, GroupZones=“Dad Mom room”, Repeat = 1}, 307)

1 Like

Hi cw-kid,

On the first 5 implemenatitions, it is just the luup code to launch the alexa message based on the inputs in this thread. in my case, it will be -

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text=“Main Door Opened”, Volume=100, GroupZones=“Dining”, Repeat = 1}, 307)

On #6, here is the luup -

local MainDoor = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 20) or “”
local EntDoor = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 21) or “”
local KitchenDoor = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 22) or “”
local MainLock = luup.variable_get(“urn:micasaverde-com:serviceId:DoorLock1”, “Status”, 18) or “”
local EntLock = luup.variable_get(“urn:micasaverde-com:serviceId:DoorLock1”, “Status”, 17) or “”
local KitchenLock = luup.variable_get(“urn:micasaverde-com:serviceId:DoorLock1”, “Status”, 16) or “”
local doors = 3 - MainDoor - EntDoor - KitchenDoor
local locks = MainLock + EntLock + KitchenLock

if (MainDoor == “0” and MainLock == “1”) then MainDoortxt = “Closed and Locked” elseif (MainDoor == “0” and MainLock == “0”) then MainDoortxt = “Closed but Unlocked” elseif (MainDoor == “1”) then MainDoortxt = “Opened” else MainDoortxt = “Unavailable” end
if (EntDoor == “0” and EntLock == “1”) then EntDoortxt = “Closed and Locked” elseif (EntDoor == “0” and EntLock == “0”) then EntDoortxt = “Closed but Unlocked” elseif (EntDoor == “1”) then EntDoortxt = “Opened” else EntDoortxt = “Unavailable” end
if (KitchenDoor == “0” and KitchenLock == “1”) then KitchenDoortxt = “Closed and Locked” elseif (KitchenDoor == “0” and KitchenLock == “0”) then KitchenDoortxt = “Closed but Unlocked” elseif (KitchenDoor == “1”) then KitchenDoortxt = “Opened” else KitchenDoortxt = “Unavailable” end

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text=doors … " Doors Closed and " … locks … " Doors Locked. The Main Door is " … MainDoortxt … ". The Entertainment Room Door is " … EntDoortxt … ". The Kitchen Door is " … KitchenDoortxt, Volume=50, GroupZones=“Dad Mom room”, Repeat = 1}, 307)

MainDoortxt = nil
EntDoortxt = nil
KitchenDoortxt = nil

#8
local DadMomRoom = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 178) or “”
local BoysRoom = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 66) or “”
local InaRoom = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 35) or “”
local EntRoom = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 73) or “”
local Dining = luup.variable_get(“urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, 224) or “”
local motion = DadMomRoom + BoysRoom + InaRoom + EntRoom + Dining

if (DadMomRoom == “1”) then DadMomRoomtxt = "Motion in Your Room. " elseif (DadMomRoom == “0”) then DadMomRoomtxt = “” else DadMomRoomtxt = "Your Room Unavailable. " end
if (BoysRoom == “1”) then BoysRoomtxt = "Motion in Boys Room. " elseif (BoysRoom == “0”) then BoysRoomtxt = “” else BoysRoomtxt = "Boys Room Unavailable. " end
if (InaRoom == “1”) then InaRoomtxt = "Motion in Ina Room. " elseif (InaRoom == “0”) then InaRoomtxt = “” else InaRoomtxt = "Ina Room Unavailable. " end
if (EntRoom == “1”) then EntRoomtxt = "Motion in Entertainment Room. " elseif (EntRoom == “0”) then EntRoomtxt = “” else EntRoomtxt = "Entertainment Room Unavailable. " end
if (Dining == “1”) then Diningtxt = "Motion in Dining. " elseif (Dining == “0”) then Diningtxt = “” else Diningtxt = "Dining Unavailable. " end

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text=motion … " Motions Detected inside Home. " … DadMomRoomtxt … BoysRoomtxt … InaRoomtxt … EntRoomtxt … Diningtxt, Volume=50, GroupZones=“Dad Mom room”, Repeat = 1}, 307)

DadMomRoomtxt = nil
BoysRoomtxt = nil
InaRoomtxt = nil
EntRoomtxt = nil
Diningtxt = nil

#9
local DadMomTV = luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 226) or “”
local KidsTV = luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 15) or “”
local SalaTV = luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 13) or “”
local EntTV = luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 12) or “”
local TotalTV = “0”

if (tonumber(DadMomTV) > 20) then DadMomTVtxt = "… The Dad and Mom room TV… " TotalTV = TotalTV + 1 else DadMomTVtxt = “” end
if (tonumber(KidsTV) > 20) then KidsTVtxt = "… The Kids room TV… " TotalTV = TotalTV + 1 else KidsTVtxt = “” end
if (tonumber(SalaTV) > 20) then SalaTVtxt = "… The Sala TV… " TotalTV = TotalTV + 1 else SalaTVtxt = “” end
if (tonumber(EntTV) > 20) then EntTVtxt = "…The Entertainment room TV… " TotalTV = TotalTV + 1 else EntTVtxt = “” end

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text=TotalTV … " TVs are powered on " … DadMomTVtxt … KidsTVtxt … SalaTVtxt … EntTVtxt, Volume=50, GroupZones=“Dad Mom room”, Repeat = 1}, 307)

DadMomTVtxt = Nil
KidsTVtxt = Nil
SalaTVtxt = Nil
EntTVtxt = Nil

#10 (this is partial as it contains similar as those shared above for the other devices)

local HomeMode = luup.variable_get(“urn:micasaverde-com:serviceId:HouseModes1”, “HMode”, 59) or “”
if (tonumber(HomeMode) == 1) then HomeModetxt =" Home Mode. " elseif (tonumber(HomeMode) == 2) then HomeModetxt =" Away Mode. " elseif (tonumber(HomeMode) == 3) then HomeModetxt =" Night Mode. " elseif (tonumber(HomeMode) == 4) then HomeModetxt =" Vacation Mode. " else HomeModetxt = " Unavailable. " end

local HomeEnergy = math.ceil(luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 308)) or “”
local DiningOutlet = math.ceil(luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 207)) or “”
local SalaOutlet = math.ceil(luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 14)) or “”
local Piano = math.ceil(luup.variable_get(“urn:micasaverde-com:serviceId:EnergyMetering1”, “Watts”, 221)) or “”

local Monitor = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”, “Status”, 297) or “”
local AqBig = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”, “Status”, 277) or “”
local AqSmall = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”, “Status”, 278) or “”
local Grotto = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”, “Status”, 279) or “”

local mylights = luup.variable_get(“urn:micasaverde-com:serviceId:PhilipsHue1”, “StateForAll”, 51) or “”
local roomlights = luup.variable_get(“urn:micasaverde-com:serviceId:PhilipsHue1”, “StateForAll”, 113) or “”

if (tonumber(DiningOutlet) > 1) then DiningOutlettxt = “… Dining Outlet consumes …” … DiningOutlet … " watts. " else DiningOutlettxt = “” end
if (tonumber(SalaOutlet) > 1) then SalaOutlettxt = “… Sala Outlet consumes …” … SalaOutlet … " watts. " else SalaOutlettxt = “” end
if (tonumber(Piano) > 1) then Pianotxt = “… The Piano is on …” else Pianotxt = “” end

if (Monitor == “1”) then Monitortxt = “… CCTV Monitor is on …” elseif (Monitor == “0”) then Monitortxt = “” else Monitortxt = “… CCTV Monitor is unavailable …” end
if (AqBig == “1”) then AqBigtxt = “… Big Aquarium is on …” elseif (AqBig == “0”) then AqBigtxt = “” else AqBigtxt = “… Big Aquarium is unavailable …” end
if (AqSmall == “1”) then AqSmalltxt = “… Small Aquariums are on …” elseif (AqSmall == “0”) then AqSmalltxt = “” else AqSmalltxt = “… Small Aquarium is unavailable …” end
if (Grotto == “1”) then Grottotxt = “… Grotto light is on …” elseif (Grotto == “0”) then Grottotxt = “” else Grottotxt = “… Grotto light is unavailable …” end

if (mylights == “1”) then mylightstxt = “… Dad Mom room lights are on …” elseif (mylights == “0”) then mylightstxt = “” else mylightstxt = “… Dad Mom room lights are unavailable …” end
if (roomlights == “1”) then roomlightstxt = “… Entertainment room lights are on …” elseif (roomlights == “0”) then roomlightstxt = “” else roomlightstxt = “… Entertainment room lights are unavailable …” end

THEN SAME AS ABOVE #6, #7, #8 & #9 BUT THE ALEXA SAY MESSAGE SHOULD BE CONSOLIDATED TO ONE AS IN-

luup.call_action(“urn:dlna-org:serviceId:DLNAMediaController1”, “Say”, {Text="System is in " …HomeModetxt… " Home Energy Consumption is " … HomeEnergy … "watts. " … DiningOutlettxt … SalaOutlettxt … Pianotxt … Monitortxt … AqBigtxt … AqSmalltxt … Grottotxt … mylightstxt … roomlightstxt … " There are " … TotalTV … " TVs powered on " … DadMomTVtxt … KidsTVtxt … SalaTVtxt … EntTVtxt … "There are " … motion … " Motions Detected inside Home. " … DadMomRoomtxt … BoysRoomtxt … InaRoomtxt … EntRoomtxt … Diningtxt … "The temperature in your Room is " … DadMomTemp … " degrees Celsius. Boys’ Room is " … BoysTemp … " degrees Celsius. Ina’s Room is " … InaTemp … " degrees Celsius. Entertainment Room is " … EntTemp … " degrees Celsius. and Dining Room is " … DiningTemp … " degrees Celsius. There are " … doors … " Doors Closed and " … locks … " Doors Locked. The Main Door is " … MainDoortxt … ". The Entertainment Room Door is " … EntDoortxt … ". The Kitchen Door is " … KitchenDoortxt, Volume=50, GroupZones=“Dad Mom room”, Repeat = 1}, 307)

Thanks ever so!

Before I start messing with it, has the quotes and stuff been corrupted by forum formatting?

I only ask 'cos you’ve not used the “```” to define it as code blocks :wink:

Thanks, again

C

the code looks exactly same as in my luup scenes no corruption on quotes. i didn’t use “```” and don’t know about code blocks. it’s all frankenstein code from google searches and tested until it works. i don’t have any formal programming lessons except basic language stuff in college, so i don’t mind suggestions and recommendations if anyone improves it. welcome :slight_smile:

1 Like

The plugin is awesome that now i made a virtual switch called “talking home” that toggles several reactor switches that enable other minor announcements inside the house such as real time kids’ room motion, real time kids room TV/door opening and other minor stuff.

The lastalexa sounds like another big upgrade. i work around now by adding scenes & routines and having code words per room in the alexa command - e.g. i have (a) “home report dining” routine/scene and (b) “home report main room” routine/scene

1 Like

I can’t keep up! :slight_smile:

I shall certainly be implementing some of this. last Alexa sounds very useful!

C

1 Like

Kudos to @therealdb for the awesome work. I have to admit that whenever I read this thread I itch to migrate in order to reduce the number of devices in my house (by removing a few sonos speakers) and use only echo devices in every room. Only wish that the announcements can be synchronized (don’t understand why they have not implemented this yet since music can already be) and that the API could be localized (My current TTS setup is cloudless openluup->SONOShttpAPI->macOSvoice->SONOShttpAPI->SONOS) but this is unlikely to happen.

1 Like

A janky way to get sync Sonos announcements that I use is to record the Alexa announcement on your phone and upload it to either your NAS or Apple Music, and have sonos play that announcement. That way you can get the Alexa voice and you can group all zones, using the sonos plugin. I’m sure there’s a better way for this but it works pretty well for me, certainly a lot of work.

thanks, but I just built on the shoulder of the giants, by using the original sh script.

I hope @edward will add jq soon to the packages, because I have it ready on my dev version and routines and lastalexa are pretty cool. I will probably release it anyway in the coming days, since it’s already working on openluup.

2 Likes

does anyone know if its possible to use LUUP code to have Alexa say what door/window is opened without having to create a custom line for each door/window. For example instead of having a bunch of "Say’ statement for each sensor you could have it say the name of the sensor that was opened. I don’t know if its clear what im trying to get at so let me know if more clarification is needed :sweat_smile:

Yes, using the scene trigger lua. Create a global variable containing the name of the door/window as the string and for each trigger set that variable to be the name of it.
In your scene you can then pull the name by using a string.format function to integrate it into your TTS string. It’s pretty straightforward once you are familiar with lua… If you need the specific codes let me know.

Yes I would need specific codes, a little too advanced for my knowledge

In the startup lua declare a global variable:
door = ""

Then in the scene editor, under each specific trigger for your scene, you should see a little button with an “L” in it. That’s the trigger lua code.
For each trigger set the variable to what you want for example:
door = "front door"

Now to create your string for your tts, you will have to compose it:
local ttsmessage = string.format("The %s is open", door)

and you can then continue on to submit the ttsmessage as your tts text string…

1 Like