Using Alexa TTS to Announce Opening of Alarm Zone

My goal is to have Alexa announce any zone that’s been opened. I have roughly 30 fish zones so writing out the LUA code for each zone would take a lot of time. I was wondering if it was possible in reactor to have all the zones in one group and have a TTS speech line that would have a variable in it that would be filled in with the name of zone that was opened. For example the TTS speech would read ‘The insert zone name has been opened’ and the zone name would automatically be filled in. I think this may be a possibility with the expressions tab but im not sure how to utilize it. I posted about this in the Alexa TTS forum as well, but the solution that Rafael kindly suggested was a little too far passed my abilities.

I had heard talk (no pun intended) of users making their Alexa devices do Text-to-Speech (TTS), but I’m a bit behind the times and can only make my Sonos Beam (which, granted, is also an Alexa device) do TTS, using the Sonos 2.0 plug-in.

If there’s a new plug-in on the way that interfaces with other Alexa-enabled devices - Echo, Spot, Dot, etc. - then that’s exciting. Seems like that would be a MUCH harder feat to pull off thru Vera, though.

Good luck with your project. Sounds pretty fun, and I’m sure someone here can guide you.

Already got the Alexa TTS part down :wink: Go have a look at this thread:

pretty straightforward stuff and more features are being added. Im stumped on the reactor part though!

(Wasn’t questioning the solidity of the Alexa TTS, only pointing out that the setup steps are not laid out in one place, and seem to involve lots of mucking about with manual installs and tweaks. Icons, github files, variables, non-Lua scripting … all scary to me.)

As for Reactor Expressions, I do think they can work in the “mail merge”-y way I suggested above, although I haven’t quite tried that approach beyond, say, using a { } variable in a Notify > SMTP scenario.

For your situation, I was suggesting that you create a (blank / expressionless) variable in Expressions, called zone_name. Then your Activities > …goes TRUE routine could assign that variable a value (whatever you want, like “Dan’s Room”), using Set Variable. And then in a subsequent step, perform a “Say” action where that same variable – {zone_name} – stands in for the zone you want spoken.

Yes, you’d still have to do this setup N times in Reactor, and I can’t think of a workaround for that. Maybe someone else smarter than me will come up with a better strategy.

  • Libra

It’s works very well actually!

Yea I am not familiar with the expressions tab so I’ll give that a try! Edit: I am unsure if im setting the variable in the expressions tab or somewhere else

Ah I understand now. Yea before I repeat this for each zone I was wondering if there was a way to only have to do it once :joy:. From what I’m getting from the expressions tab it may be possible to get the name of the variable that went true in the group.

I think you’re on the right track. Some suggestions (if you’re not already reading the Reactor Docs about ‘Expressions’ over on ToggledBits.com)… this is just pseudocode…

zone1=if(<device.state of zone one>=“tripped”,“Zone One”, “”)
zone2=if(<device.state of zone two>=“tripped”,“Zone Two”, “”)

zones_all=zone1+zone2

zones_tripped = if(len(zones_all)>0,“The following zones were tripped” + zones_all, “No zones tripped.”)

And use {zones_tripped} somewhere in your SAY statement?

It’s so late here that I may not be thinking straight. :wink:

Will give this a try… I read the docs but my limited understanding of code only goes so far. Stay tuned …

1 Like

So the rest of what you’re saying is making sense however im stuck at setting the expression for this part ‘zone1=if(<device.state of zone one>=“tripped”,“Zone One”, “”)’ I set the variable name to for my case ‘Bar Doors’ = if(<device.state of Bar Doors>=“tripped”,“Bar Doors”, “”) I don’t think that’s correct how ive used it

Everything I typed to this point has been pseudocode, not actual Reactor expressions, sorry. I’ll chime in again tomorrow when I have more time to cut-and-paste actual expressions.

1 Like

Bumping this maybe @rigpapa can provide some insight whether this is possible

I’m not a Reactor expert, but this is doable in code. How are your sensors setup? Do you have anything that can be used to filter them? the idea is to add a watch for Tripped variable, after cycling them, and when set to 1, run your TTS code, automatically getting the name from the sensor. I can try to write some code in case you need more help. If you can’t discriminate them, you can easily write down their IDs the first time, and then run the very same code against your array of device IDs. This could be handy when you don’t want to include a device in your routine anymore.

Yes. It is possible.

Would you be able to help me out, it’s read all relevant reactor docs and still am a bit lost.

I’m on vacation at the moment, and won’t be home until mid-week.

The gist of what you want to study is this:

  1. Let’s say you make an expression variable called sensors that contains an array of the sensors you want to monitor: list(31,44,127,212)
  2. You can use this with the iterate() expression function to make an array of tripped sensors in tripped_sensors = iterate( sensors, if( getstate( _, "urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped") == "1", _, null ) )
  3. You can make an array of the names of those sensors in tripped_names with iterate( tripped_sensors, getattribute( _, "name" ) )
  4. You can make a text message out of that with "Alert Zones " + join( tripped_names, ", " ) [note there is a space after the comma inside the second parameter to join()]

You can then send that string to your TTS if the number of tripped sensors > 0. Then len() function will give you the length of the array.

1 Like

All good, thought you were back already. Enjoy the rest of the trip I’ll try out some things with that info thanks :blush:

Here’s my current set up

Group TTS Alarm -(And)
-Group House Modes -(XOR)
- House is any of: night, away or vacation
-Group Alarm Zones -(OR)
-list of all the alarm zones

I believe what Rigpapa said is what you’re suggesting. Listing the devices, then referencing that list to see which devices are tripped and having a line of code spit out the names into a line of speech.

1 Like

So I was able to get the expressions up and running! Now im just stuck on the TTS part. From my understanding each expressions results are stored in a state variable. How would I insert the ‘message’ state variable into my TTS string that looks like this:

luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text=“{message} has been opened”, Volume=50, GroupZones=“Arman’s Sonos One”, Repeat = 1}, 632)

luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”, {Text= ..message.. "has been opened", Volume=50, GroupZones=“Arman’s Sonos One”, Repeat = 1}, 632)

I think will do it. Where ‘message’ is the name of your variable

C

You don’t need Lua. Choose a Device Action in the activity, choose your TTS device, Say action, and set Message to {message}. Note that you cannot include other text there. It can only be {message}. If you want more text prepended/appended, do it in the expression that creates message as my example shows.

Also note that Sonos plugin uses a different definition for GroupZones. In Sonos, only values ALL or CURRENT or blank are allowed. If you want to specify devices, they go in GroupDevices. Not sure how the Alexa TTS approached this but it looks like it’s different.

1 Like