Amazon Echo Skill EchoToEventGhost

If you have a question or need help, this is the place to be.
Post Reply
m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Amazon Echo Skill EchoToEventGhost

Post by m19brandon » Wed Sep 23, 2015 4:33 am

## EchoToEventGhost

This looks better in my GitHub project's readme.md https://github.com/m19brandon/EchoToEventGhost

UPDATE VERSION v2.2 07/04/2017
Changes:

1. Added a Welcome post to EG (allows for a custom responses, I'm suggesting an event bases on the time and past event history)
2. The post to EG now has 4 objects in the payload('spoken string', deviceid, sessionid, requestId)
3. Rewrote some of the code, it should look much cleaner
4. Moved to Node.js 6.10 (Should work with Node.js 4.3)

UPDATE VERSION v2.1 03/26/2016
Changes:

1. Added support for EventGhost's Webserver Basic Auth
2. Better response code handling

UPDATE VERSION v2 03/23/2016
Changes:

1. Result Parsing for unknown command so Alexa can re-prompt if needed.
2. Added result parsing for custom voice speechOutput.

***********************************

Hope all enjoy. :D

If you are like me, you have been using EventGhost for home automation because you want the customized control this platform allows. Or you are nuts and spend your nights writing code only you will ever see and use. If this is you, you may also have an Amazon Echo seating in the kitchen. Now this $180 kitchen timer is great, but it can do so much more. Now with this new skill, you can pass any spoken command to EventGhost where this intent becomes actionable.

This is a simple AWS Lambda node.js script that packages up the Alexa Skills Kit Intent and will post any spoken command to your EventGhost Webserver as an Event with a payload.

I have added the option to parse the body of the return response from EG webserver to allow for custom replies back. (IE. User: Q - is the garage open. Alexa: A - Yes the garage has been open for 30 minutes)

## Getting Started with EchoToEG

The guide below was mostly copied from this link https://developer.amazon.com/alexa-skil ... t-tutorial I recommend using both, Amazon's has screen shots.

## Step 1 (Create your AWS Lambda function that your skill will use)

1. Download or clone my EchoToEventGhost github project https://github.com/m19brandon/EchoToEventGhost
2. Make sure you have your EventGhost Webserver is running and you can post to from outside your network.
* Get Your External IP, https://whatismyipaddress.com/
* Plus the post that your have configured for the Event Ghost webserver to run on (80 is default). If you need help with configuring port forwardinglook here http://www.wikihow.com/Set-Up-Port-Forw ... n-a-Router
* To test goto http://ip:port/page?event ie. http://192.168.1.1:80/index.html?EG_Event and a event should be logged in EventGhost
3. If you do not already have an account on AWS, go to Amazon Web Services and create an account.
4. Log in to the AWS Management Console and navigate to AWS Lambda.
5. Click the region drop-down in the upper-right corner of the console and select either **US East (N. Virginia)** or **EU (Ireland)**.
Lambda functions for Alexa skills must be hosted in either the **US East (N. Virginia)** or **EU (Ireland)** region.
6. If you have no Lambda functions yet, click **Get Started Now**. Otherwise, click **Create a Lambda Function**.
7. Under the blueprints, click **Blank Function**.
8. Click in the empty box and select **Alexa Skills Kit**, then next.
9. For the function name enter **EchoToEGv2**, the Description can be left blank, and for the runtime select **Node.js 6.10**
10. Under the **Lambda function** code section leave as **Edit code inline** and then copy in my code.
The code can be found under [\EchoToEventGhost\AlexaSkillKit_Code\EchoToEGv2.js](https://github.com/m19brandon/EchoToEve ... oToEGv2.js)
You will need to edit some variables in the code.
* Line 16: Is your EventGhost Webserver using http and https
* Line 18: Enter your External IP
* Line 21: Enter the port number you configured in the EventGhost Webserver
* Lines 29 & 30 are your EventGhost Webserver user name and password
11. Under the **Lambda function handler and role** section, leave **Handler** and **Role** as is and for **Existing role** select "lamba_basic_execution"
12. Leave the other sections as is and click **Next** and then on the next page click **Create Function**
13. Under **Actions** you can test your function by using the **Configure test event**, change the name of **Hello World** as needed and pasted the contents of [\EchoToEventGhost\AlexaSkillKit_Code\EchoToEG_TestEvent.xml](https://github.com/m19brandon/EchoToEve ... tEvent.xml) (Line 22 is the command that is passed) and then **Save and Test**
If all works you could see an event in your EventGhost log.


## Step 2 (Create your Alexa Skill and link your Lambda function)

1. Sign in to the **Amazon developer portal**. If you haven’t done so already, you’ll need to create a free account. https://developer.amazon.com/edw/home.html#/
2. From the top navigation bar, select **Alexa**.
3. Under **Alexa Skills Kit**, choose **Get Started >**.
4. Choose **Add a New Skill**.
5. Name your skill. This is the name displayed to users in the Alexa app. **Event Ghost** is a good choice.
6. Create an invocation name. This is the word or phrase that users will speak to activate the skill. **Event Ghost** is a good choice. Amazon recommends against signal word invocation name. Click **Save**.
7. Choose **Next** to continue to development of the new skill.
8. In the **Intent Schema** box, paste the JSON code from [\EchoToEventGhost\AlexaSkillKit_Code\IntentSchema.txt](https://github.com/m19brandon/EchoToEve ... Schema.txt)
9. Skip over the **Custom Slot Types** section.
10. Under **Sample Utterances** paste in contents of \EchoToEventGhost\AlexaSkillKit_Code\Utterances.txt
11. Choose **Next** and wait until the interaction model finishes loading, in no more than a few seconds
12. Select the Endpoint AWS Lambda ARN then paste your ARN code. Select North America as your region, and for Account Linking select No, then choose Next.

* This code can be found under the Lambda function create in steps 1.
arn:aws:lambda:us-east-1:#:function:EchoToEGv2
13. There is a new **testing tool under the testing tab**. Logs can be found here https://console.aws.amazon.com/cloudwatch
14. There is no need to Publish the skill.

## Step 3 (EventGhost, add some code to make stuff happen)

1. Create a new Python Script Macro, copy in the contents of [\EchoToEventGhost\EventGhost_Code\PythonScriptExample.py](https://github.com/m19brandon/EchoToEve ... Example.py)
2. Copy [\EchoToEventGhost\EventGhost_Code\index.html](https://github.com/m19brandon/EchoToEve ... index.html) into your webserver folder
3. From your EventGhost log, drag the HTTP.EchoToEG event into that macro to fire whne you did your testing in step 1 & 2.
3. Test your Skill
************
Examples:

* "Alexa, Tell INVOCATION_NAME lights on"
* "Alexa, Tell INVOCATION_NAME to change the channel to ESPN"
* "Alexa, Tell INVOCATION_NAME to turn off the bedroom lights"
Attachments
EchoToEGv2.2.zip
(10.12 KiB) Downloaded 54 times
Last edited by m19brandon on Mon Jul 10, 2017 1:54 am, edited 5 times in total.

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Sat Mar 19, 2016 2:42 am

Has anyone used this Alexa Skill? I see that code has been downloaded a lot. My family uses the Amazon Echo as our main controller through EG for the house :)

Does anyone need anything added or changed. I just order the Echo Dot so I need to start passing the device ID in the payload post. My personal version of this Alexa skill is a little different because I have much more EG code between the webserver's response in order to allow for more human interaction but I can also backport the device id into this version too.

Thanks, B

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Wed Mar 23, 2016 2:50 am

m19brandon wrote:Has anyone used this Alexa Skill? I see that code has been downloaded a lot. My family uses the Amazon Echo as our main controller through EG for the house :)

Does anyone need anything added or changed. I just order the Echo Dot so I need to start passing the device ID in the payload post. My personal version of this Alexa skill is a little different because I have much more EG code between the webserver's response in order to allow for more human interaction but I can also backport the device id into this version too.

Thanks, B

I've been trying to register on this site just to say you're a life saver. I've been trying to get another person solution using an https server working but I haven't had any luck. I downloaded your solution and had it working in no time.

If you're taking requests I wish I could pass a response back to the echo. For instance I use it to control iTunes, I wish I could ask Alexa which song iTunes is playing and have it respond.

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Wed Mar 23, 2016 10:40 pm

I use personal version that does custom responses base on a Webserver variable being set in eg. I will share the code later tonight.

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Thu Mar 24, 2016 12:22 am

m19brandon wrote:I use personal version that does custom responses base on a Webserver variable being set in eg. I will share the code later tonight.
That would be awesome. I'll keep an eye out for it.

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Thu Mar 24, 2016 3:10 am

New version (v2) has been posted. I have updated the steps too. Thanks @DanRoss for the input.

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Thu Mar 24, 2016 3:30 am

m19brandon wrote:Thanks @DanRoss for the input.
Thank you for sharing this with the rest of us. I'll play with it tomorrow.

One more request if it's even possible, is there a way to use this while having basic authentication enabled on the web server? I have another use that needs it and I was hoping to do both from the same server. If it's not possible or if it's too much effort don't worry about it. I'm grateful enough for what you've given already.

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Thu Mar 24, 2016 6:15 pm

Could you post a sample of one of the macros this jumps to? When I'm testing my skill in the Alexa online test page I'm not seeing a custom response back that I thought I would. I'm sure I'm doing something wrong.

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Thu Mar 24, 2016 10:51 pm

I don't just 'Jump and Return' once but have a few nested, but the code below is what builds one of the responses. All responses are set to 'eg.globals.ibl1_msg' which is what is set to the Webserver.SetValue 'bb_response' in the macro provided with the EchoToEG code. That bb_response value is then posted on the index.html page.

What is your response if you just go to http:://IP/index.html?EchoToEG&test in your web browser?

I will work on Basic Auth, it was the next item on my list already. I just have been lazy.

Macro that test the index.html:

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="1722">
    <Action>
        Webserver.SetValue(u'bb_response', u'{eg.globals.ibl1_msg}', False, False)
    </Action>
</EventGhost>

Python Code I use to build my response and run my home automation events for my TV.

Code: Select all

intent = eg.globals.bb_get_intent
conf = eg.globals.bb_get_conf
entities = eg.globals.bb_get_entities
action = ''
search_query = ''
channel = ''

msg = ''
rtn_msg = ''

def getChannelNumber(query):
	channel_num = ''
	if query <> '':
		print 'Searching for channel ' + query
		for channel in eg.globals.family_channel_list:
			if channel[1].lower() == query.lower():
				channel_num = str(channel[0])
				print 'Channel ' + query.lower() + ' is ' + channel_num
	else:
		print 'Cannot search var, string was empty'

	return channel_num

if 'action' in entities:
    if 'value' in entities['action'][0]:
        action = entities['action'][0]['value']
        print 'Action: ' + action
    else:
        msg = msg + '\nAction Not Found'
        print 'Action Not Found'
else:
    msg = msg + '\nAction Not Found'
    print 'Action Not Found'
    
if 'search_query' in entities:
    if 'value' in entities['search_query'][0]:
        search_query = entities['search_query'][0]['value']
        print 'Search Query: ' + search_query
    else:
        msg = msg + '\nSearch Query Not Found'
        print 'Search Query Not Found'
else:
    msg = msg + '\nSearch Query Not Found'
    print 'Search Query Not Found'

if 'channel' in entities:
    if 'value' in entities['channel'][0]:
        channel = entities['channel'][0]['value']
        print 'Channel: ' + channel
    else:
        msg = msg + '\nChannel Not Found'
        print 'Channel Not Found'
else:
    msg = msg + '\nChannel Not Found'
    print 'Channel Not Found'

trg = ''

if action == 'off':
    trg = 'ip2ir_Family_All_Power_Off'
    rtn_msg = 'turning off the family room tv'
elif action == 'computer':
    trg = 'ip2ir_Family_Set_to_DVD'
    rtn_msg = 'setting the family room tv to the computer'
elif action == 'tv' or action == 'channel':
    if channel == '' and search_query == '':
        trg = 'ip2ir_Family_Set_to_Cable'
        rtn_msg = 'lets watch tv'
    else:
        if channel <> '':
            ch = getChannelNumber(channel)
        else:
            ch = ''
        if search_query <> '':
            sq = getChannelNumber(search_query)
        else:
            sq = ''
        if ch <> '' or sq <> '':
            if ch <> '':
                eg.globals.family_cable_tune_to = ch
                rtn_msg = 'setting the tv to ' + channel
                print 'Found channl via channel value'
            else:
                eg.globals.family_cable_tune_to = sq
                rtn_msg = 'setting the tv to ' + search_query
                print 'Found channl via search query value'
            trg = 'ip2ir_Cable_Tune_To'
        else:
            trg = 'ip2ir_Family_Set_to_Cable'
            rtn_msg = 'but i do not know channel, ' + channel + search_query
elif action == 'music':
    trg = 'ip2ir_Family_Set_to_Music'
elif action == 'movie':
    trg = 'ip2ir_Family_Set_to_Movie'
elif action == 'netflix':
    trg = 'ip2ir_Family_Set_to_Netflix'
elif action == 'xbox':
    trg = 'ip2ir_Family_Set_to_Xbox'
    rtn_msg = 'xbox on, good luck'
elif action == 'mute':
    trg = 'ip2ir_Onkyo_Mute'
elif action == 'volume_down':
    trg = 'ip2ir_Volume_Down_5'
elif action == 'volumne_up':
    trg = 'ip2ir_Volume_Up_5'
else:
    print 'cmd is unknown: ' + action
	
if trg != '':
    eg.globals.ibl1_ttl = eg.globals.ibl1_ttl + ': ' + trg
    eg.globals.ibl1_msg = eg.globals.ibl1_msg + '\nTrigger: ' + trg
    eg.globals.ibl1_msg = eg.globals.ibl1_msg + '\nReturn Msg: ' + rtn_msg
    eg.TriggerEvent(trg)
    print trg
else:
    eg.globals.ibl1_msg = eg.globals.ibl1_msg + '\ncmd is unknown: ' + action
#Done

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Fri Mar 25, 2016 12:06 am

m19brandon wrote:
What is your response if you just go to http:://IP/index.html?EchoToEG&test in your web browser?
I have this python command to set the response to whatever I put in for testing

eg.globals.ibl1_msg = eg.event.payload[0]

when I go to the link you provided the web page displays test or whatever I put in in place of the word test.

I changed the command to

eg.globals.ibl1_msg = "Your playlist is playing"

With that I go to the same link and no matter what I put in place of test I get "your playlist is playing" as I would expect it to.

Now I go to the test function inside the Alexa developer portal and enter the utterance play playlist. I would expect the response to come back and say "your playlist is playing" but I get the following:

Code: Select all

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "Got it, working on the command, play playlist"
    },
    "card": {
      "content": "Got it, working on the command, play playlist",
      "title": "Echo To EventGhost - Black Box Automation",
      "type": "Simple"
    },
    "reprompt": {
      "outputSpeech": {
        "type": "PlainText",
        "text": "I could not understand, please try again"
      }
    },
    "shouldEndSession": true
  },
  "sessionAttributes": {}
}

Am I wrong to think the response would have included "Your playlist is playing"

My ultimate goal is to ask Alexa to ask iTunes which song is playing, have it run my iTunes control script that grabs the current song playing, have EG set a variable with the song title and pass that back to Alexa to tell me the name of the song.

*edit - I forgot to add I have not tried this speaking to Alexa yet. Only testing I've done is on the PC.

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Fri Mar 25, 2016 12:21 am

I think you are close. I have coded the node.js function to parsing the post for 'Return Msg: ' and then splitting that line for the response.

Try
eg.globals.ibl1_msg = 'Return Msg: ' + eg.event.payload[0]
OR
eg.globals.ibl1_msg = 'Return Msg: ' + 'Your playlist is playing'

If you wanted it to re-prompt as if the command was unknown try

eg.globals.ibl1_msg = 'cmd is unknown: '

Sorry, I was not clear in the setup steps.

I will take a look later. Off to see Batman :)

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Fri Mar 25, 2016 1:26 am

m19brandon wrote:I think you are close. I have coded the node.js function to parsing the post for 'Return Msg: ' and then splitting that line for the response.

Try
eg.globals.ibl1_msg = 'Return Msg: ' + eg.event.payload[0]
OR
eg.globals.ibl1_msg = 'Return Msg: ' + 'Your playlist is playing'

If you wanted it to re-prompt as if the command was unknown try

eg.globals.ibl1_msg = 'cmd is unknown: '

Sorry, I was not clear in the setup steps.

I will take a look later. Off to see Batman :)

That was what I was missing. Everything is responding as I expected. Now to build the rest of it.

The ultimate plan is to control iTunes, have the ability to cast the audio from iTunes to my audio chrome casts that are connected to my inside and out side receivers and set the volume on them all from my Echo..

Well there's much more on the ultimate plan but that's one of the steps to get there.

Enjoy Batman, have a popcorn on me...

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Fri Mar 25, 2016 4:51 am

Glad it worked. I have Alexa doing everything now and I get my Amazon Dot in a few days for the bedroom.

I would recommend using something like 'Wit.AI', as it makes getting the meaning and intent out of spoken words easier.

DanRoss
Posts: 19
Joined: Wed Mar 23, 2016 2:15 am

Re: Amazon Echo Skill EchoToEG

Post by DanRoss » Sat Mar 26, 2016 12:33 am

I've never used that before but from what I just saw of it wouldn't it be just as easy to create intents within the Alexa skill?

I still have to look further into it so I can get a better understanding of what it is.

If I were to create intents within the skill would they pass through the Lambda function and make it to EG?

m19brandon
Experienced User
Posts: 177
Joined: Mon Feb 03, 2014 10:36 pm

Re: Amazon Echo Skill EchoToEG

Post by m19brandon » Sat Mar 26, 2016 12:44 am

Yes, the Amazon avs would work just as well.

Post Reply