本文只是提供一个简单的思路,以一种比较简单的方式把自己使用arduino制作的硬件连接到Amazon Alexa中,可以使用Amazon Echo等设备控制它。
原文地址:http://blog.csdn.net/luhanglei/article/details/54289986
效果:http://weibo.com/tv/v/EpwDW1ktb?fid=1034:35b0913deed1b50f38fbad52f4c03382
大体的原理如图所示
我选择java做服务器语言,完整开发需要了解并实现oauth的过程、servlet或jsp、socket通信
1.硬件环境:首先需要配置Amazon Echo,按照说明书配置好即可,不过多描述。
2.云服务器:准备好一个云服务器,必须要有一个固定的端口号给server socket(主要是让arduino跟自己的服务器同步数据用,如果有更好的解决方案,请忽视)。我采用的是bae和它的扩展服务中的port服务,因为用起来比较熟悉。如果会node.js或者python,也可以直接使用亚马逊的AWS Lambda。
注意申请完port之后要把port和你的bae应用绑定起来,就是把port映射到你bae应用的某一个端口上。
3.亚马逊的配置:注册skill
到亚马逊开发者网站的Alexa管理页面,选择Alexa Skills Kit,然后新建一个Skill
①选Custom Interaction Model,并填写插件的名字。选智能家居后面的部分步骤会比选普通插件麻烦,如果想尝试的朋友也可以尝试直接使用智能家居的选项。
填好后选择next
②填写你要用到的口令的相关信息(JSON格式)
Intent Schema,可以理解为定义一下你命令中可能出现的一些东西,比如设备、动作
以下是亚马逊提供的Intent Schema的实例
{
"intents": [
{//以上为固定格式
"intent": "GetHoroscope",//intent的名字,在下方命令定义中,针对这个intent的命令必须以引号中的字符开头
"slots": [
{
"name": "Sign",//slot的名字,比如你要操作好几个设备,这里可以是设备
"type": "LIST_OF_SIGNS"//slot对应的type,在下方的输入框中会进行定义,比如定义的type是机器,那么type可以在下方的定义中可以包含灯、插座等
},
{
"name": "Date",
"type": "AMAZON.DATE"//亚马逊也给出了一些默认的type,如果需要可以查看,因为我控制的是净化器,没有用到
}
]
},
{
"intent": "GetLuckyNumbers"
}
]
}
假如我需要从空气净化器读取我家里的空气质量,那我只需要把Intent Schema定义成下面的样子
{"intents":[{
"intent":"air",//intent会被发送到自己的服务器,告诉自己是要获取空气质量
"slots":[{
"name":"quality",//给关键词定义名字为质量
"type":"QUALITY"//slot的类型为QUALITY,至于关键词到底有什么,会在Slot type中定义
}]
}
]
}
Slot Type
比如:在machine中定义light和switch等词语,这里的词语不再是一个类别的名称,而是你命令中确切会出现的词语。特别注意,最后亚马逊发送给我们服务器的消息只包含了命令的intent的名字、slot的名字和type中具体的口令词,不会包含type的名字。
还是以获取空气质量为例:
要在QUALITY这个type中加入air quality、dust、PM2.5等词语,关键词之间换行分割即可。
这一步是要给出命令的范例,还是拿空气质量举例
air How is the {quality} in the house
其中air是intent的名字,空格后是命令,{quality}是一个通配符,是slot的名字,Alexa会把它匹配到上一步定义的air quality、dust、PM2.5等词语中。
③把自己的服务器关联到Alexa,让Alexa知道把消息传递到哪。
图片上方要填写的地址就是当Alexa收到我们的命令之后,把json post的目的地址。
下半部分为用户绑定相关设置。因为牵扯到智能家居控制,所以最好选择绑定账户,可以在我们自己的服务器上区分用户是谁。
grant type选择 implicit grant比较简单,就是很常见的oauth的认证方式,只不过这次我们的角色变成了token的颁发方,Alexa引导用户来获取token。当第一次打开插件的时候,Alexa APP会把用户引向我们填写的Authorization URL,由我们进行认证,在认证完成后,按照要求重定向到图中所示的Redirect url中,完成账户的绑定。
认证完成后,我们让用户重定向的地址类似于:
https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=AAAAAAAAAAAAAA#state=xyz&access_token=2YotnFZFEjr1zCsicMWpAA&token_type=Bearer
其中#之前的是亚马逊给我们的重定向地址,后面的参数需要我们添加上。
state
是在亚马逊请求Authorization URL的时候,会带过来的一个参数,此处需要传回去。
access_token
就是我们给予用户的令牌。
token_type是固定值,Bearer
。
此外网页中其他的数据分别是:client-id,输入的数值会在亚马逊请求的时候发送给我们用于识别。scope是Alexa需要请求的权限,也是我们自己定义的,我瞎填的。
④SSL Certificate
这一步是亚马逊要求我们的服务器必须是有效的sll证书的。因为我是用的是bae,所以直接选My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority即可,bae是支持https的,应该所有的二级域名都有证书。
⑤测试
前面都按步骤设置好的话,就可以打开测试了。打开测试以后,可以在网页下方的Service Simulator输入文字命令查看自己服务器的返回结果是不是正确。也可以在Alexa APP中的skill中的your skills中看到自己的skill了!
到这里,亚马逊的配置就完成了。
ARDUINO连接到服务器
我用的是esp-13的wifi板,使用arduino uno的软串口连接。连接到服务器的方式比较简单,在esp-13的配置界面里把模式改成client,然后把在bae申请到的port的ip和端口号填进去就行了。
【此处有坑】我申请的时候port的端口号总是在30000多,esp-13的提交总显示非法数值。解决方法是:除了端口号之外,其他东西照常填,端口号瞎填一个30015以下的数字。提交。然后刷新一下,把esp的配置界面保存下来,用文本编辑软件打开,把javascript中进行端口号合法性检查函数的返回值直接改为永远是true。然后把post配置信息的相对地址改成以ip开头的绝对地址进行提交,就可以正常使用了。
arduino和服务器之间就可以通过socket进行数据交换了。
服务器的几个接口
1.oauth授权的页面,alexa的app打开这个页面,确定用户身份后按规定跳转回指定的redirect url。
2.Alexa发来的信息交互
发来的信息的样式可以在test中看到
回复的格式为:
{
"version": "1.0",
"response": {
"outputSpeech": {"type":"PlainText","text":"Text to speak back to the user."},//text中是语音回复的内容
"card": {//显示在Alexa APP中的内容
"type": "Simple",
"title": "Example of the Card Title",
"content": "Example of card content. This card has just plain text content.\nThe content is formatted with line breaks to improve readability."
}
}
}
3.一个server socket,跟arduino通信
大体过程就是这样,如果有什么需要补充的欢迎在评论中提出,如有错误欢迎批评指正。