米家与Homekit搭建智能家居指南(二)



实在非常抱歉,因为本人本职工作最近负责开发一个项目,一月赶工无休,所以实在没法抽出时间更新这个系列,现在项目有一些模块已经上线,时间相对宽裕一些,遂把这个坑填了。
同步更新在[少数派]

前情回顾

上一章题目是[入门智能家居,从米家到HomeKit(一)]

主要讲的是在树莓派上通过HomeBridge把米家智能家居接入到iOS的HomeKit中。

本章来讲的是,跳出米家智能家居,讲一讲高级版自动化

这一章我们除了使用到上一章的HomeBridge,还会使用HomeAssistant。
那么,问题来了:

0. HomeKit、HomeBridge、HomeAssistant分别是什么?关系是什么?

0.1. 概念

HomeKit:苹果于2015年5月发布的智能家居平台。
HomeBridge:一个开源程序,用于让HomeKit支持一些原生不支持HomeKit的设备(如米家家居)。
HomeAssistant:一个第三方的智能家居平台。

0.2. 关系

  • 上一章的关系图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
+---------------------+
| MiJia |
+---------------------+
|
|
v
+---------------------+
| HomeBridge-Mi-Aqara |
+---------------------+
|
|
v
+ - - - - - - - - - - - - +
' Common: '
' '
' +---------------------+ '
' | HomeBridge | '
' +---------------------+ '
' | '
' | '
' v '
' +---------------------+ '
' | HomeKit | '
' +---------------------+ '
' | '
' | '
' v '
' +---------------------+ '
' | You | '
' +---------------------+ '
' '
+ - - - - - - - - - - - - +

可以看到,上一章米家设备通过插件HomeBridge-Mi-Aqara来与HomeBridge沟通,让我们的iphone通过Siri(HomeKit)来接入HomeBridge达到最终控制米家设备的目的。

  • 本章的关系图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
+---------------+
| MiJia |
+---------------+
|
|
v
+----------------+ +---------------+ +--------------------------+
| Bluetooth Lock | --> | HomeAssistant | --> | HomeBridge-HomeAssistant |
+----------------+ +---------------+ +--------------------------+
^ |
| |
| v
+- - - - - - - - - - - - - - - +
' Common: '
' '
+---------------+ ' +--------------------------+ '
| IFTTT | ' | HomeBridge | '
+---------------+ ' +--------------------------+ '
' | '
' | '
' v '
' +--------------------------+ '
' | HomeKit | '
' +--------------------------+ '
' | '
' | '
' v '
' +--------------------------+ '
' | You | '
' +--------------------------+ '
' '
+- - - - - - - - - - - - - - - +

可以看到,这一章将要介绍的情况,米家、IFTTT这些智能家居并没有直接接入到HomeBridge,而是先接入到第三方智能家居平HomeAssistant,然后HomeAssistant与HomeBridge通过插件HomeBridge-HomeAssistant进行交互沟通,最后把结果反馈到你的手机上。

0.3. 我为什么要搞多一个HomeAssistant?

因为接入了HomeAssistant,能够给你的家居智能化上升到一个新的高度。

HomeBridge因为自身的一些条件限制,以及条件束缚,只能够一次控制一类家居,比如HomeBridge-Mi-Aqara就只能控制米家类家居。

而HomeAssistant能够做到,如果天气预报说要下雨了,网关灯变红,多云变黄,晴天就变绿啊,或者是爸爸回家了手机自动联入wifi,会发推送告诉我不要看小视频了等等,可以说,让更多的事情加入到智能化这一行列。

让事情变得更好玩,更有趣,更智能,是我引入HomeAssistant的目的所在。

0.4. 我想告诉你的

如果你是希望用iphone或者siri控制一些米家家居,或者回到家打开门台灯自动亮起来欢迎你,那么其实[上一章内容]已经完全满足你的需求,已经OK了。
这一章虽然带来了很多新的有趣的骚操作,但是因为引入了HomeAssistant,所以也会相应的增加了操作量,所以你要自我衡量考虑一下要不要继续折腾噢~
涉及到的新操作IFTTT, 动态域名解析, Liunx部分新命令

1. 开始前的准备

准备:

  1. 你需要有一个树莓派,它是一个已知IP地址, 开启了SSH, 干净正常耐操的树莓派。
  2. 希望你最好有linux的基础。

通关路线:

  • 如果对于上面两条你已经做到了,那么直接从往下看。
  • 如果你是完全按照上一章内容操作,并且完成了所有功能实现,那么请看这里,为你跳过重复部分
  • 如果你对于这个准备毫无头绪,不妨先回顾一下[上一章内容],在上一章的第0~1章有相应的手把手教学

2. 整个应用框架的安装

2.1. 安装NodeJS

在终端中输入

1
2
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs


安装完要使用nodejs -v看看版本是不是v6.xx,如果不是的话,再次执行这两条命令。

2.2. 安装avahi包

在终端中输入

1
sudo apt-get install libavahi-compat-libdnssd-dev

2.3. 安装HomeBridge

在终端中输入

1
sudo npm install -g --unsafe-perm homebridge

2.4. 安装HomeBridge-HomeAssistant

在终端中输入

1
sudo npm install -g homebridge-homeassistant

2.5. 安装HomeAssistant

在终端中输入

1
sudo pip3 install homeassistant

2.6. 配置HomeAssistant

2.6.1. 初始化HomeAssistant配置文件

在终端中输入

1
2
mkdir ~/.homeassistant
vim ~/.homeassistant/configuration.yaml

在打开的编辑器中,单击键盘的i键,进入输入状态
复制以下初始化内容到文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
homeassistant:
# Name of the location where Home Assistant is running
name: Home
# Location required to calculate the time the sun rises and sets
# 设置你的经纬度,判断日落时间
latitude: 42.7683
longitude: 129.3364
# Impacts weather/sunrise data (altitude above sea level in meters)
elevation: 0
# metric for Metric, imperial for Imperial
unit_system: metric
# Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
time_zone: Asia/Shanghai
# Show links to resources in log and frontend
introduction:
# Enables the frontend
frontend:
# Enables configuration UI
config:
http:
# Uncomment this to add a password (recommended!)
# 这里推荐设置一个登陆密码
api_password: HaHb7890
# Uncomment this if you are using SSL/TLS, running in Docker container, etc.
# base_url: example.duckdns.org:8123
# Checks for available updates
# Note: This component will send some information about your system to
# the developers to assist with development of Home Assistant.
# For more information, please see:
# https://home-assistant.io/blog/2016/10/25/explaining-the-updater/
updater:
# Optional, allows Home Assistant developers to focus on popular components.
# include_used_components: true
# Discover some devices automatically
discovery:
# Allows you to issue voice commands from the frontend in enabled browsers
conversation:
# Enables support for tracking state changes over time
history:
# View all events in a logbook
logbook:
# Track the sun
sun:
# Weather prediction
sensor:
- platform: yr
# Text to speech
tts:
- platform: google
group: !include groups.yaml
automation: !include automations.yaml

然后点击键盘esc,输入:wq进行保存并推出编辑器。

2.6.2. 安装HomeAssistant初始化所需要的插件

HomeAssistant安装完后,其实只是安装了一个主体程序,实际上还需要安装很多小控件的安装,往往需要Root权限,所以在终端中输入

1
sudo hass --open-ui

等待程序自动运行,他会安装一些homeassistant所需要的一些组件。
我们可以在浏览器中输入http://树莓派IP地址:8123进行访问,去了解HomeAssistant是否初始化成功。


当你的浏览器看到这个页面,表示已经成功初始化插件安装了。这个时候你需要按住Ctrl+C(mac电脑是Control+C)来退出这个程序,一直按到你出到能输出命令的终端页面。如下图所示:

注意,以Root权限运行的HomeAssistant在实际操作中发现,并不能按照我们的配置文件进行配置,所以我们还需要以当前用户pi权限来运行HomeAssistant。

然后在终端中输入

1
hass --open-ui

等待片刻,我们用浏览器访问http://树莓派IP地址:8123,如果你在前面配置文件中有设置密码HaHb7890,就会显示一个登陆页面,说明你能够正式使用HomeAssistant系统了。

2.6.3. 记录米家智能家居硬件的相关信息

打开米家APP(小米智能家居官方硬件),选择智能网关设备,点选右上角的···功能符号,进入后点选关于

然后你看到的是下图左边的样子,这时候你需要疯狂输出,要不断的点击空白处,片刻后界面就会变成右边的样子,多了局域网通信协议还有网关信息选项。

这时候,分别点选他们,记录你的网关的局域网通信协议密码以及网关的MAC地址,请记好噢。

2.6.4. 把HomeAssistant配置米家智能家居

需要注意的是,HomeAssistant在50.0版本后,已经从官方上集成对小米智能家居,所以我们直接在HomeAssistant配置文件上配置即可。
在终端中输入

1
vi ~/.homeassistant/configuration.yaml

进入编辑器后,按住shift然后单击键盘g键,会自动跳转到最后一行(vim的G键代表跳到最后一行)。然后单击键盘o键,开始进入编辑模式。
输入以下字段:

1
2
3
4
xiaomi:
gateways:
- mac: B827EBDA70F9(你的树莓派MAC地址,地址中间如果加`-`会报错)
key: 通讯密码(请全部大写,不然只能看智能家居状态不能控制)

然后,单击键盘esc键,再输入:wq进行保存退出。

ok,配置好,就要软重启一下HomeAssistant,进入HomeAssistant页面,选择左下角的Developer Tools(开发者工具)下的第一个图标,然后在右边的标签页中填写相应的信息:

  • Domain: homeassistant
  • Service: restart
    然后点击CALL SERVICE来唤起HomeAssistant的重启。

原理介绍:HomeAssistant把很多功能都以组件来看待,然后我们就是调用了核心组件homeassistant里面其中一个方法restart来对HomeAssistant进行重启。

这个时候,homeassistant的页面会告诉你已经与服务器断开连接了,事实上你只要静静地等待就好了,等到重新正常连接就ok了。但是耐不住寂寞的你肯定想看看进度如何对吧,这个时候,你知道打开刚刚输入了hass ==open-ui代码的终端窗口,就可以看到实时情况,如下面的截图就是说,我在安装的过程中,而且安装过程已经超过10s了。

稍安勿躁,去泡杯茶回来,网页版的HomeAssistant已经能够正常连接了,你点击左边栏的States按钮,回到总览页面,你就可以看到,小!米!智!能!家!居!出!现!了!

ok,那说明你的小米智能家居已经成功的接入了HomeAssistant平台了,恭喜你往高端玩家又进了一步请继续阅读下文哈。

2.7. 配置HomeBridge-HomeAssistant

在终端中输入

1
2
3
mkdir ~/.homebridge
cd ~/.homebridge
vi config.json

在打开的文件界面中,单击键盘的i键,进入输入状态
复制以下内容到文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"bridge": {
"name":"Homebridge",
"username":"B8:27:EB:DA:70:F9",
"port":51826,
"pin":"233-78-123"
},
"platforms": [
{
"platform": "HomeAssistant",
"name": "HomeAssistant",
"host": "http://127.0.0.1:8123",
"password": "HaHb7890",
"supported_types": ["binary_sensor", "climate", "cover", "device_tracker", "fan", "group", "input_boolean", "light", "lock", "media_player", "remote", "scene", "sensor", "switch"]
}]
}

  • bridge-name : 你在iphone的HomeKit上面看到桥接设备网关的名称
  • bridge-username : 树莓派MAC地址
  • bridge-port : HomeBridge使用的端口,默认就好
  • bridge-pin : 在iphone上认证HomeBridge网关的密码,这个按照你自己喜好来输入吧
  • platforms-host : 你访问HomeAssistant的地址+端口
  • platforms-password : 你在HomeAssistant设置的登陆密码

2.8. 配置HomeBridge

在终端中输入

1
homebridge -D

运行成功后,会如下图所示:

2.9. iOS的HomeKit配置

进入家庭APP,添加配件,你就可以看到HomeBridge了

把里面的配件添加进来,你的homekit就已经具备了他应该有的功能了。

2.10. 设置长久运行的Homebridge

事实上,你现在如果关闭了SSH链接,那么你的Homekit也会处于失效状态,因为你的Homebridge随着SSH的连接关闭导致被关闭了,如果解决?

使用SCREEN工具,在终端下输入:

1
sudo apt-get install screen

然后输入

1
2
screen -dmS hb homebridge # 开启一个名字叫做hb的窗口并运行homebridge命令,hb这个名字你随意取
screen -dmS ha hass --open-ui # 开启一个名字叫做ha的窗口并运行'hass --open-ui'命令,hb这个名字你随意取

在screen里开启的homebridge不会随着SSH关闭而被关闭。那么如何暂时退出这个窗口呢?

先按Ctrl+A然后按完再按一下d就可以跳出来做其他事情了,如何回去?使用screen -x hb即可。

2.11. 设置开机自启动HomeBridge & HomeAssistant

事实上,树莓派关机后,两个程序会被关闭,可以使用SCREEN工具,并且在rc.local里面添加开机自启动任务。
在终端中输入

1
sudo vi /etc/rc.local

然后进入了编辑器,单击键盘的i键进入编辑模式。在exit 0这一行前面添加:

1
2
su -c "screen -dmS hb homebridge" -s /bin/sh pi
su -c "screen -dmS ha hass --open-ui" -s /bin/sh pi

然后单击键盘esc退出编辑模式,然后输入:wq保存文件并推出编辑器。

2.12. 设置远程化运行的Homekit

苹果规定,homekit一般情况下,只能在同一个wifi下操作,如果你要远程化和自动化操作。请充(yao)值(mai)信(mai)仰(mai)!

远程控制起步是ipad mini2 或者 apple tv3

自动化起步是ipad mini2 或者 apple tv4

[地址戳我]

3. 联动IFTTT的骚操作开始

终于来到激动人心的时刻了,要开始真正的骚操作了。

3.1. IFTTT是什么,干嘛用

3.2. 给HomeAssistant配置IFTTT组件

类似小米智能家居的通信密钥,IFTTT有一个key,从[Webhook这个位置]获取得到。
拿到之后,在终端中输入以下命令:

1
vi ~/.homeassistant/configuration.yaml

进入编辑器后,按住shift然后单击键盘g键,会自动跳转到最后一行(vim的G键代表跳到最后一行)。然后单击键盘o键,开始进入编辑模式,输入以下字段:

1
2
ifttt:
key: xxxxx_xxxxxxxxxxxxx

然后,单击键盘esc键,再输入:wq进行保存退出。

然后按照上面的教程,重新restart一下HomeAssistant.

3.3. IFTTT作为触发条件

做一个简单演示,如果我们用HomeAssistant调用了IFTTT,就给手机版的IFTTT发一条推送。
作为IF条件,Event Name就是我们给这个事件声明的名字,我们以HA_TEST来做这个事件的声明名字。

然后触发条件,选择Notification,推送的内容,可以设置一些预设的变量函数,包含我们给这个事件声明的名字Event Name,也可以包含我们传过去的Value值。

创建完IFTTT的Applets,我们回到HomeAssistant测试一下。
在HomeAssistant的Developer Tools的第一个图标,然后配置如图。DATA一般是以JSON格式来传输的。

点击调用后,几秒钟你的手机的IFTTT就会给你发来一条推送了。

实际上,用HomeAssistant还能用内置的automation来调用IFTTT,相当于内置的IFTTT,但是支持的控件没IFTTT那么丰富。

3.4. IFTTT作为触发结果

ok,前面是一个小的应用,最主要的还是要介绍IFTTT作为触发结果。

3.4.1. HomeAssistant API

HomeAssistant支持丰富的API,通俗来说,就是你访问一个网络地址就能控制你家的台灯开与关
ok,地址是http://树莓派地址:8123/api/services?api_password=登陆密码,你可以看到所有HomeAssistant能支持的API,抽取其中一个给大家介绍一下。
其中一个是关于对灯光的API介绍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
domain: "light",
services: {
turn_on: {
description: "Turn a light on",
fields: {
brightness: {
description: "Number between 0..255 indicating brightness",
example: 120
},
color_name: {
description: "A human readable color name",
example: "red"
},
entity_id: {
description: "Name(s) of entities to turn on",
example: "light.kitchen"
},
rgb_color: {
description: "Color for the light in RGB-format",
example: "[255, 100, 100]"
}
}
}
}
}

所以你发起一个POST请求,我是使用了Mac版的Paw软件来发起请求,当然你可以使用Chrome上面的PostMan扩展来做测试。
我请求的地址是/api/services/light/turn_on然后附上URL的PARAMS是entity_id代表要开的灯的id,然后附上API调用密码api_password.
然后在主体BODY PARAMS里面写入灯光的颜色color_name,以及亮度brightness

1
2
3
POST 192.168.1.100:8123/api/services/light/turn_on?entity_id=Gateway_Light_34ce0088d139&api_password=HaHb7890
Body Params {"color_name":"red","brightness":"50"}


调用后,你家里的网关灯就会变红了,而且亮度设定在50.

3.4.2. 如果明天下雨,我的网关灯要变红

流程图

1
2
3
4
5
6
7
8
+ - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - -+
' IFTTT: ' ' HomeAssistant: '
' ' ' '
' +----------+ +----------+ ' ' +-------------------+ +------+ '
' | 外面下雨 | --> | 调用事件 | ' --> ' | HomeAssistant API | --> | 灯亮 | '
' +----------+ +----------+ ' ' +-------------------+ +------+ '
' ' ' '
+ - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - -+

其实关于HomeAssistant部分,我们在3.4.1已经介绍了。现在需要介绍IFTTT设定以及IFTTT如何调用HomeAssistant.

3.4.2.1. 域名动态解析

我们现在调用的API地址是一个局域网的地址,形如192.168.x.x,这个在广域网(互联网)是无法调用的,简单来说就是,你在公司的网络是调用不了你在家里的这台树莓派的API的,更何况IFTTT。
所以,为了解决这个问题,你可以:

  • 购买固定IP。
    向宽带提供商ISP购买一个固定IP,无论你如何重启路由器啊,这个IP就是能指向你家路由器,这个一般费用比较高昂,不推荐。
  • 使用动态解析域名(推荐)
    现在一般的路由器都内置了动态解析的组件,可以把内网的某一个机器的某一个端口映射到指定的域名端口,或者整个内网机器映射到外网,推荐前者,比较安全。具体自己找方法啦
  • 内网穿透
    可以了解一下ngrok

3.4.2.2. IFTTT设置

IF条件,你可以选择IFTTT中的Weather Underground中的Current condition changes to触发器,选择Rain。代表,如果天气预报发现你那里快要下雨了,就触发这个事件。

THEN条件,选择IFTTT的webhook:

  • 请求地址URL跟我们的3.4.1中的地址一样,只是树莓派的地址和端口换成动态解析后的域名与端口
  • 请求方法METHOD选择POST,
  • 传输内容类型Content Type选择application/json,
  • 传输内容Body写关于灯光的详细配置,颜色变红亮度50{"color_name":"red","brightness":"50"}
  • 点击Creata action进行保存

最后,Review一下,给这个自动化设定一个名字,下面的按钮的意思是每次出发了这个自动化,要不要给你手机的IFTTT发一个推送证明它发送了。

OK,那么整个流程到这里就算是完成搞掂了~

其实这个流程有1点不太安全的是,IFTTT的POST请求明文调用了树莓派的API密码,我研究了一下好像IFTTT的Applet只会针对个人,不对外分享,所以还算是安全。然后动态解析尽量针对端口吧,对外开放太多端口容易受到攻击,同时API密码请申请的高强度一下,SSH使用密钥登陆。