您的位置:首页 > 产品设计 > UI/UE

把arduino以简单的方式接入Amazon Alexa实现语音控制

2017-01-09 18:12 447 查看
本文只是提供一个简单的思路,以一种比较简单的方式把自己使用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等词语,关键词之间换行分割即可。

Sample Utterances
这一步是要给出命令的范例,还是拿空气质量举例

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通信

大体过程就是这样,如果有什么需要补充的欢迎在评论中提出,如有错误欢迎批评指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息