Can I Have webCoRE direct Output to the Last Active Echo Speaks Alexa Device?

So far, I am able to create automations that result in a particular bit of text being spoken aloud from a particular Alexa device using Echo Speaks in webCoRE. This is great! :slight_smile:

Now, I want to see if there is a way of having the Alexa device that speaks the text be dynamic.
i.e. I want it to come out of the one that I was last speaking with (Whereas right now, it’s just coming out of whichever one I specified in the webCoRE piston).

I think I may have even seen this concept discussed previously, but I forget where, and can’t find it at the moment.

Can this be done?

Yes it can be done. I use a combination of two webcore pistons.

One piston triggers on waslastspokento=true for all of the devices I care about and stuffs the one that triggered the change into a global variable.

The second piston uses whatever device is in the global variable as the rltarget Alexa device.

Caveat: was last spoken to is only updated by Echo Speaks approximately every 60 seconds. So if you have just spoken to a specific device that was different than the previous last spoken to and you’re experiencing response to come back to that device you might get unexpected results.

3 Likes

OK. Thanks.
I see.

Is there any way of manually, programmatically triggering Echo Speaks to reevaluate for waslastspokento? If so, I could add that command into the piston to have it happen before the command to say something.

You can try issuing GetDeviceActivity(), but I think for it to work you’d have to do it for your entire list of Echo’s probably in a foreach loop.

https://tonesto7.github.io/echo-speaks-docs/devicesupport/commands/action_commands/#getdeviceactivity

So basically before you make your voice call, stuff all your echo devices in a device list variable then ‘do’ a ‘for each’ device in devicelist: .getdeviceactivity()

I haven’t tried this because the 1 minute resolution is plenty good for what I’m doing.

3 Likes

I guess that seems like a bit too much for me to get into just to have Alexa say something in exactly the way I’m wanting. lol I’m also assuming it would probably take too long for the system to go through all that in order for it to have the response be timely enough to seem natural.

Oh well.

Thanks, man. :slight_smile:

1 Like

It works! Big thanks to you!!!

4 Likes

Eric you may be able to get away with not having the call to get device activity in that particular piston.

Reason, you’re triggering on one of the echos changing waslastspokento to true. So when that happens, webcore has already noted a change in the subscribed device and fired the trigger. So updating the activity is redundant.

You’ll want the call to update the activity BEORE you call any speech command that you want to place like this.

It would be more like this…
Call to GetDeviceActivity (possibly in its own utility piston to refresh latest status and possibly trigger your last spoken to piston)
Call to Speech command (to lastspokento)

Other than that optimization, looks good. Hope it works for you

It works perfectly as is. I have a central speaking piston for all the others. They are activated first, and then the output is sent to that piston. The getactivity command gets the Echo information almost as quickly as a normal Alexa command.

[EDIT] Ok, I take that back. It’s 99% fast enough.

Thanks for sharing the piston! :slight_smile:

First, I’m assuming I have something messed up, or maybe just don’t understand, but…

I didn’t fully understand it at first, but I imported it to give it a try anyway.
I thought maybe this was going to be something that I would add to a piston to help with directing Echo Speaks traffic. However, as I sit here and test speaking commands to different Alexa devices, I see that this thing is updating the variable automatically shortly after my voice interactions.

I am seeing an error in the logs when it runs, but it still appears to be working.

That is very cool!!
Regardless of the rest of my questions, I will probably leave this thing in place.

Now, with the delay I’m seeing, this would not be a viable solution for the thing I’m looking for.
Is there any way to sort of build this into a piston to have this info available mid-stream in an automation?

Is that just simply a matter of me understanding what’s happening here, and plugging the appropriate parts into my piston?

…and/or is that what @nathancu is talking about after your comment? lol

EDIT:
Oh wait…I see now that it is a local variable, and not global.
I guess that means I should be able to use it in a piston.
So, I will give it a try lol …

UPDATE:
omg, it’s working! lol
holy smacks! :slight_smile:

3 Likes

And this is why I live this community! We may be a small number compared to the millions who use ST but “we” are the pioneers!

ST by itself is cool but Custom Codes and this Community is FREAKING AWESOME!!!

3 Likes

Totally agree.

I have the global variable set, but I can’t figure out how to use it.
I did all kins of searching, and read through all kinds of threads about global variables, but I just don’t see it anywhere, and it is not available when I go to build a piston to use it.

So… @mebejedi how do I actually use it? :embarrassed:

Here’s how I use mine:
This piston is a generic piston I use anytime I’m trying to do a speech announcement. It accepts a few arguments - sMessage being the message itself. The other arguments are a set of flags that determine how the announcement behaves, do I do the last Echo, a subset of echos or ALL of my echos. I’m also monitoring the status of a virtual switch to determine if the alert will happen at all. (Wife Acceptance Factor). It’s not at all finished but it’s workable.

Notice I’m basically setting up a list of devices to target based on the flags… You could clean that all out if you want. The default no argument ‘null’ condition on bAnnounce and bOverride sends the announcement to the last spoken Echo device. This requires the Global Variable @LastSpokenTo to be not NULL

Now @LastSpokenTo is set within 60 seconds any time an Echo updates its .wasLastSpokenTo attribute to TRUE in this piston:

So whenever I call the speech piston it doesn’t have to ask - it just points and shoots. I did not find any good reason to update the device status - 60 seconds resolution is good enough for me.

This is an example of calling the Speech piston from another. I have a piston that evaluates whether my garage doors SHOULD be open and if not, alerts by message and voice. (Yes, I know I have some work to do in this one both for optimization and to handle multiple alerts at once, but it gets the job done.)

A lot of code here - but it should help you see how it all fits together.

2 Likes

OK…this is great!

Now…imagine for a moment…wait…no…it’s true…so…
remember that I’m an idiot, and all I can handle is one simple action. lol

Can you show me how to simply send a msg, via Echo Speaks, to the global variable representing the last spoken to Alexa device?

i.e.
If THIS HAPPENS
Using GLOBAL VARIABLE
Speak THIS MSG

(or whatever the format needs to be)

Sure, First Piston - Line 42, 52, 56… :slight_smile:

(BTW, I used to be a teacher so this is as good of a clue I’m going to point at - you’ll do better if you figure out what’s happening in these pistons. This is homework. You’re getting there - keep it up!)

1 Like

OK…while I really freakin appreciate your input, and will, at some point, LOVE to take advantage of that kind of teaching format, unfortunately, as of right now, I am not able to dedicate the necessary brain power or time it appears necessary to consume and synthesize all of that. :slight_smile:

So… are you saying that the simple way I’m looking for (which I normally use in other pistons to send notifications to Echo Speaks devices) simply can’t be done when the device I want to send it to is being represented by a global variable (even though, when it is being represented by a local variable, I can)?

1 Like

No I’m saying what you’re looking for are those three lines.
42: I set the Value of a local variable devSpeakEchoDevices to the contents of the global variable @LastSpokenTo
52: Crap I should have said 50 - my error - need new glasses. This entire clause is WITH devSpeakEchoDevices (It could have just been @LastSpokenTo if we’re trying to simplify this)
we
56: DO Speak Text with the variable sMessage which contains my message

You already set @LastSpokenTo in the other piston, so with those together it should go.

1 Like

OK…so, line 42 is how you get the global variable brought into the current piston and use it as a local variable?

Basically yes. OR you could just call it as the device itself. Instead of picking one of your echoes, pick that.

Now when picking a variable that stores a device, sometimes the UI wigs out and won’t show you all the methods available. What I like to do is use an actual device and get it working the way I want, then go and edit the code to change the device to my variable.

1 Like

So basic piston just to get it working is:

And then I edit the device used to be:

Note the same global variable @LastSpokenTo instead of an actual device…

1 Like

© 2019 SmartThings, Inc. All Rights Reserved. Terms of Use | Privacy Policy

SmartThings; SmartApps®; Physical Graph; Hello, Home; and Hello, Smart Home are all trademarks of the SmartThings, Inc.