智障家居初战-语音控制篇(基于Node-RED对接)

现在的整体方案较当初设想有不少变化,首先是中控系统由domoticz换成了Home Assistant(Home Assistant的界面更好看);另外是语音控制终端由天猫精灵换成了Echo音箱(阿里搞什么实人认证,不想折腾了);控制点、采集点由esp8266模块换成了sonoff模块(sonoff集成度更好、取电也更方便)和米家的产品(米家的使用体验好是好,就是贵)。
本篇主要介绍:Echo音箱与Home Assistant的对接以及全流程测试。


1.HA

1.1安装

建议ubuntu环境安装,参考教程

2.2终端设备

准备一个可控制的“智能”设备,在此以sonoff为例,可以参考教程章节1-3准备一个。

3.3控制api

后续对接服务调用HA的api进行控制,使用chrome浏览器的postman插件进行测试。

http://{[HA服务器ip]}:8123/api/services/switch/turn_on?api_password={[HA密码]}

{'entity_id':'switch.template'}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//响应样例
[{
"attributes": {
"friendly_name": "测试"
},
"context": {
"id": "1898701755c24dd58c41df43d32fa4d1",
"user_id": null
},
"entity_id": "switch.template",
"last_changed": "2018-09-14T03:32:28.422597+00:00",
"last_updated": "2018-09-14T03:32:28.422597+00:00",
"state": "on"
}]

2.Echo音箱

前往开发者平台创建一个自定义技能,并关联到Echo,这样Echo就能将我们的语音指令翻译成Json格式指令并发送到我们指定的接口服务器。后续再根据指令调用HA的api来对终端设备进行控制。

2.1创建skill

  • 输入技能名称,类型选”Custom”,点击”Create Skill”按钮。

DEBUG:其实更建议选”Smart Home”,Amazon定义好了很多标准属性,更加适合智能家居场景,不过指令的处理需要使用AWS Lamaba,不能用自己的服务。

  • 默认第一个即可,点击”Choose”继续。
  • “Build”标签页加载如下,在这我们对Skill进行配置,可以看到1-4步骤是必须的。

2.1.1 Invocation

  • 点击左侧面板”Invocation”,设置调用名称,默认是和技能名称一样。

INFO:设置完毕点击”Save Model”保存,后续不再提及。

2.1.2 Intent

  • 点击左侧面板”Intents”,打开页面中点击”Add Intent”。
  • 创建一个意图。假设我们目的是控制灯,创建一个”LightControll”意图。

DEBUG:意图(intent)是在语言处理模块与执行模块之间传递信息的一种比较通用的格式标准,可以简单认为是用户命令的形式化描述。

INFO:意图名称”LightControll”会传递给接口服务器,然后我们就知道这是控制灯。

  • 一个意图需要设置Sample Utterances和Intent Slots。

INFO:Sample Utterances是不同的说话样例,比如我们关灯可以说“打开厨房的灯”和“把厨房的灯打开”。然后Intent Slots是说话样例中的变量,我们“打开厨房的灯”、“打开客厅的灯”,“客厅”、“厨房”就是一个位置变量,用一个Slot代替。

  • 在这我创建两种话例:”turn {sate} the {zone} light”、”turn the {zone} light {state}”Utterances。其中包含两个变量{state},代表开灯还是关灯;{zone},代表灯的位置。

DEBUG:当增加的话例中含有{xxx},会自动创建对应名称的slot。

  • 还要为slot设置类型,点击左侧面板”Slot Types”,然后点击”Add Slot Type”。
  • 自定义即可,输入名称”CUSTOM_ZONE”,点击”Create custom slot type”。
  • 依次添加”kitchen”和”living room”,作为测试就不添加多了。

DEBUG:如果设置同义词”SYNONYMS”,那应该设置”ID”,这样对接服务器根据”ID”来判断具体位置。

  • 类似添加”CUSTOM_STATE”,两个值”on”、”off”分别对应开、关,。
  • 点击左侧面板”LightControll” Intent返回先前页面,为”zone”、”state”设置SLOT TYPE。
  • 点击上方”Save Model”,再点击”Build Model”,需要等待一段时间。

2.2配置

2.2.1 Endpoint

  • 点击左侧面板”Endpoint”,点击HTTPS,输入接口服务器的API地址https://{[你的域名]}/gate。下拉框是选择证书类型,一般选My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority.

DEBUG:我们服务器与Alexa Skill服务器对接的网址,负责处理Json指令请求,具体实现见4.2章节。
WARN:需要使用HTTPS以及默认的443端口。

2.2.2 ACCOUNT LINKING

  • 点击左侧面板”ACCOUNT LINKING”,打开开关,选择”Auth Code Grant”
  • “Authorization URI”填https://{[你的域名]}/authorize.php;”Access Token URI”填https://{[你的域名]}/token.php;”Client ID”填alexa;”Client Secret”填alexa;”Client Authentication Scheme”选择Credentials in request body;”Redirect URLs”中挑选一个(选择一个可以ping通的域名即可)。

INFO:认证服务网址的内容见3.1章节

2.2.3 Oauth服务

参考教程2.2.②章节创建好数据库,增加一个用户即可。

1
2
3
4
#Ubuntu
mysql -u root -p #登陆Mysql
> use oauth; #选择数据库
> INSERT INTO oauth_clients (client_id, client_secret, redirect_uri) VALUES("alexa","alexa","https://pitangui.amazon.com/api/skill/link/xxx"); #增加认证用户(信息与上小节设置一致)

3.对接

3.1公网服务

参考教程部署公网访问服务器,其中oauth认证服务采用之前的即可。之前设置接口服务器的API网址为https://{[你的域名]}/gate,接下来只要apache2将请求转发给Node-Red服务器即可。
Node-Red安装参考教程

  • apache2配置,假设Node-Red的访问地址是http://192.168.0.100:1880。
    1) # a2enmod proxy
    2) # vi /etc/apache2/sites-available/default-ssl.conf
    3) 在<VirtualHost></VirtualHost>标签内加入

    1
    2
    ProxyPass /gate http://192.168.0.100:1880/gate
    ProxyPassReverse /gate http://192.168.0.100:1880/gate

    4) # service apache2 restart

    WARN:注意不要把根目录/进行反向代理,不然外网可以访问Node-Red了。

  • Node-red配置,设置登陆密码,加强安全。

    1) # docker exec -it {[Node-Red容器名]} bash
    2) root@xxxx# node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" password

    1
    root@xxxx# $2a$08$BpwjQlfQEtuT8z5ZfwiTqeDBauNkMeVYMl4vbNrmxd89o1/WeGtRm

    3) root@xxxx# vi /data/settings.js
    4) 找到adminAuth,注释掉adminAuth,password处填第2步生成的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    adminAuth: {
    type: "credentials",
    users: [{
    username: "{[用户名]}",
    password: "{[密码]}",
    permissions: "*"
    }]
    },

    5) 返回到宿主机,# doecker restart {[Node-Red容器名]}使配置生效。

    DEBUG:配置password保存的是加密后的字符串。

4.业务处理

Node-Red搭建业务处理节点,因篇幅有限,加上本人对Alexa的交互了解有限,所以在此只介绍下大体处理流程,详细的实现还是要耐心去看看官方的文档。

DEBUG:采用Node-Red进行对接的最大的好处就是灵活扩展,基本流程上扩充即可,可以一边学习一边不断完善。

5.联调

  • 点击’ALL SKILLS’,可以看到开发的技能。
  • 点击’ENABLE’启用技能,会跳转到授权页面。
  • 认证成功会返回如下页面。
  • 返回开发者平台的技能页面,在上方点击’Test’标签打开测试页面,输入指令可以进行测试。
  • 文字指令测试正常,可以进行真机测试。