让 Homekit 不再鸡肋,树莓派、 Homebridge 、AC86U 的 Mixture!

前期

设想

去年寒假前我的房间里重新上了漆,就买了一台小米空气净化器 2。空气净化器通过 WiFi 连接网络,我可以通过米家 App 管理我的空气净化器。但是每次要调空气净化器的时候必须要打开米家 App,等上十几秒再进行操作,着实有点麻烦。尤其是在有 Homekit 的 iPhone 上,这样的操作总是令人尴尬。
后来发现有 Homebridge 这样的项目,可以给 Homekit 增加很多自定义功能,包括连接第三方非 Homekit 验证的智能设备,甚至非智能设备也可以通过插件支持 Homekit 。于是心血来潮,查了很多资料,正好手上有一个树莓派可以做服务器,let’s begin!

设备

路由器:华硕 AC86U
服务器:树莓派 3B
智能设备:小米空气净化器 2

Homebridge 与 小米空气净化器 2 配置过程

固定 IP 地址设置

家用路由通常是打开 DHCP 的,也就是说新的连接设备获取的 IP 地址是动态的。为了后面步骤的可行性,一定要先给树莓派和小米空气净化器 2 配置固定的 IP 地址。具体设定步骤可自行谷歌或百度。

树莓派安装 Node.js 环境

Homebridge 需要通过 npm 安装,首先需要配置 Node.js 环境。
SSH 连接至树莓派,输入以下安装 Node.js :

sudo apt-get install nodejs
sudo apt-get install npm

或者源码安装的方法也行,可以参考菜鸟教程中 Node.js 的 Ubuntu 安装方法:https://www.runoob.com/nodejs/nodejs-install-setup.html

安装完成后可以通过以下测试是否安装成功:

root@Raspberry_Server:~/.homebridge# node -v
v10.7.0
root@Raspberry_Server:~/.homebridge# npm -v
6.1.0

安装 Homebridge

Homebridge 的 Github :https://github.com/nfarina/homebridge ,里面讲了如何安装 Homebridge ,不过不是很详细,我在安装的时候碰到不少问题,所以多写一写详细过程。

先安装 Homebridge

sudo npm install -g --unsafe-perm homebridge

按照 GitHub 上的说法,--unsafe-perm 是为了避免出现权限问题,如果没有这个参数会出现没有权限的警告:

gyp WARN EACCES user "root" does not have permission to access the dev dir "/root/.node-gyp/5.5.0"

安装完成后执行:

homebridge

会看到提示:

root@Raspberry_Server:~/.homebridge# homebridge
Couldn't find a config.json file [snip]

Homebridge 的配置文件为 ~/.homebridge/config.json~ 为用户目录。如果是默认 pi 用户,那么目录为 /home/pi ,如果是 root 用户,那么目录为 /root 。此处建议在 root 下创建这个文件夹,方便后面设置开机启动。

那么我就按照 root 用户的方法继续:
此时在 root 用户下创建配置文件,并用 Vim 编辑器编辑:

cd ~
mkdir .homebridge
vim config.json

在文件中添加:

{
        "bridge":{
                "name": "Homebridge",
                "username": "CC:22:3D:E3:CE:30",
                "port": 51826,
                "pin": "031-45-154"
        },
        "description": "This is my homebridge", 
}

这是一个 json 格式的文件,可以看到 bridge 下有几个对象,其中:
name :这个配件在 Homekit 中显示的名字
username :一个类似于 MAC 地址的字段,按默认的填写就行
port : Homekit 的通讯端口,采用 TCP 协议,确保树莓派的这个端口开放即可
pin : iPhone 在 Homkit 中配对时的配对码,在后面操作中配对的时候可以扫描二维码配对,可以不用刻意记住
description: 随便写什么都可以,好像也没在哪里能再看到它了….

那么到这里 Homebridge 就算是配置完了,接下来要给 Homebridge 安装插件,让它支持我的小米空气净化器 2。

安装 homebridge-mi-air-purifier 插件

homebridge-mi-air-purifier 插件的 GitHub :https://github.com/seikan/homebridge-mi-air-purifier
homebridge-mi-air-purifier 插件可以通过 npm 安装,同时它也依赖 miio 插件,因此需要安装两个插件:homebridge-mi-air-purifiermiio

npm install -g homebridge-mi-air-purifier miio

让小米空气净化器 2 和树莓派连接在同一局域网内,然后通过 miio 命令获取空气净化器的信息:

miio discover --sync

然后等待一会,出现下面的信息:

Device ID: 49466088
Model info: Unknown
Address: 192.168.1.8
Token: 6f7a65786550386c700a6b526666744d via auto-token
Support: Unknown

记下 Address 和 Token 的值,然后修改 Homebridge 的配置文件 ~/.homebridge/config.json :

{
        "bridge":{
                "name": "Homebridge",
                "username": "CC:22:3D:E3:CE:30",
                "port": 51826,
                "pin": "031-45-154"
        },
        "description": "This is my homebridge", 
        "accessories": [
                {
                        "accessory": "MiAirPurifier",
                        "name": "Bed Room Air Purifier",
                        "ip": "192.168.1.8",
                        "token": "6f7a65786550386c700a6b526666744d",
                        "showTemperature": true,
                        "showHumidity": true,
                        "showAirQuality": true,
                        "showLED": true,
                        "showBuzzer": true
                }
        ]
}

accessories 中的每个对象里都有这几个键值对,其中:
acccessory :配件的型号或者标识,不可更改。
name :在 Homekit 中显示的名字,可以自行更改。
ip :空气净化器的 IP 地址,即上一步中需要记下的 Address 。
token :空气净化器的 Token ,即上一步中需要记下的 Token。
showTemperature :是否显示温度,填 truefalse

可以看到 accessories 是一个数组 ,也就是说它支持添加多个配件。如果有两个空气净化器,配置文件可以这么写:

{
        "bridge":{
                "name": "Homebridge",
                "username": "CC:22:3D:E3:CE:30",
                "port": 51826,
                "pin": "031-45-154"
        },
        "description": "This is my homebridge", 
        "accessories": [
                {
                        "accessory": "MiAirPurifier",
                        "name": "Bed Room Air Purifier",
                        "ip": "192.168.1.8",
                        "token": "6f7a65786550386c700a6b526666744d",
                        "showTemperature": true,
                        "showHumidity": true,
                        "showAirQuality": true,
                        "showLED": true,
                        "showBuzzer": true
                },
                {
                        "accessory": "MiAirPurifier",
                        "name": "NAME_OF_AIR_PURIFIER",
                        "ip": "IP_ADDRESS_OF_AIR_PURIFIER",
                        "token": "TOKEN_OF_AIR_PURIFIER",
                        "showTemperature": true,
                        "showHumidity": true,
                        "showAirQuality": true,
                        "showLED": true,
                        "showBuzzer": true
                }
        ]
}

以此类推。
接下来添加其他的配件,也是需要在数组中添加对象,只不过不同类型的配件,对象中的键值对不尽相同。

那么到这里 Homebridge 已经成功与小米空气净化器 2 连接,接下来就让 iPhone 接入令人兴奋的家庭应用吧!

iPhone 与 Homebridge 连接

首先在 iPhone 上打开家庭应用,点击开始使用,然后点击加入配件:
点击开始使用,然后点击加入配件
然后在树莓派的 SSH 中输入:

homebridge

如果工作正常,应该会有如下显示:

root@Raspberry_Server:~# homebridge
[8/2/2018, 7:00:22 AM] Loaded config.json with 1 accessories and 0 platforms.
[8/2/2018, 7:00:23 AM] ---
[8/2/2018, 7:00:25 AM] Loaded plugin: homebridge-mi-air-purifier
[8/2/2018, 7:00:25 AM] Registering accessory 'homebridge-mi-air-purifier.MiAirPurifier'
[8/2/2018, 7:00:25 AM] ---
[8/2/2018, 7:00:25 AM] Loading 1 accessories...
[8/2/2018, 7:00:25 AM] [Air Purifier] Initializing MiAirPurifier accessory...
Setup Payload:
X-HM://0023UTGR67DPM
Scan this code with your HomeKit app on your iOS device to pair with Homebridge:
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------

Or enter this code with your HomeKit app on your iOS device to pair with Homebridge:

    ┌────────────┐
    │ 031-45-154 │
    └────────────┘

[8/2/2018, 7:00:25 AM] Homebridge is running on port 51826.
Discovered Mi Air Purifier (zhimi.airpurifier.m1) at 192.168.1.8

上面那六行短横线是一个二维码,在应用中扫描二维码后,选择仍然添加:
扫描二维码后出现提示

然后就是一堆配件啦,疯狂点击下一步添加:
点击下一步添加配件

那么最终显示的界面大概是这样的:
家庭应用主界面
到这里就成功地把小米空气净化器 2 接入 Homebridge 并且在家庭应用中显示啦!

设置开机启动

Homebridge 在运行之后不能关闭 SSH 窗口,不然就会自动关闭。那么为了让 Homebridge 在开机的时候自动启动并且后台运行,需要为它设置开机启动。为了方便查看 Homebridge 的运行状态,我想让 Homebridge 的输出内容写入日志文件,在我需要的时候可以打开查看状态。那么我这里用 nohup 命令,让 Homebridge 后台运行并写入日志:

sudo nohup homebridge > /var/log/homebridge.log 2>&1 &

设置开机启动有多种方式,可以自行谷歌或百度。在这里我选择修改 /etc/rc.local 文件:

sudo vim /etc/rc.local

在 exit 0 前添加一行代码:

sudo nohup homebridge > /var/log/homebridge.log 2>&1 &

这样就可以让 Homebridge 开机启动,并且自动将输出内容写入日志文件,便于日后维护。

小结

到这里基本的配置就结束啦!其实仔细看,我的主界面不止有小米空气净化器 2 的配件,还有我的华硕 AC86U 路由器几个重要部件的温度显示。如果只想把空气净化器接入,那么这篇文章就到此为止啦。但如果你的路由器也是华硕 AC86U ,或者自己也想搞一个温度显示,那么可以继续往下看,参考我的做法。

让 Homebridge 告诉我 AC86U 的体温

实现构思

要想在 Homekit 中查看 AC86U 的体温,首先需要知道如何获取 AC86U 的温度。在华硕路由论坛(http://www.52asus.com)中查找相关资料,很快找到了方法:
(论坛链接:http://www.52asus.com/thread-3819-1-1.html

在 AC86U 上执行命令:
核心温度:cat /sys/class/thermal/thermal_zone0/temp
2.4G温度:wl -i eth5 phy_tempsense
5G温度:wl -i eth6 phy_tempsense

那么知道了如何获取 AC86U 的温度之后,就要让 Homebridge 能够获取这个温度。
Homebridge 有个插件 homebridge-http-temperature-humidity ,可以通过 HTTP 的 GET 请求从服务器获取温度和湿度,那么我现在需要做的,就是搭建一个服务器,能 Telnet 到我的 AC86U,获取温度并返回给 Homebridge
为了方便,我用树莓派做服务器,用 Apache 2。服务器脚本用 Python 编写,通过 Telnet 到 AC86U 返回数值,我用的版本是 Python 3.5。

知道了如何实现之后,接下来就是实战了。

编写脚本

编写脚本需要有一点点 Python 基础即可,没有什么需要特别多说的。
但是有一点需要说明的是,脚本是通过一个名为 application 的函数与服务器建立交互的,其中形参有 environstart_response,返回值就是服务器返回的数据。

#!/usr/bin/env python
#coding=utf-8
def application(environ, start_response):
    output = 'test'
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return output

根据 homebridge-http-temperature-humidity 插件的说明,返回值是 json 格式,包含两个对象:temperaturehumidity。这里没有湿度的数据,所以返回的内容只需包含 temperature 即可。

为了方便,这里给出了获取 CPU 温度的脚本 cputemp.wsgi ,获取 2.4G 和 5G 温度的可以根据以下修改:

#!/usr/bin/env python
#coding=utf-8
def application(environ, start_response):
    import telnetlib
    Host = '192.168.1.1'
    username = 'username'
    password = 'password'
    tn = telnetlib.Telnet(Host, port=23, timeout=10)
    tn.read_until('login:'.encode('utf-8'))
    tn.write((username + '\n').encode('utf-8'))
    tn.read_until('Password:'.encode('utf-8'))
    tn.write((password + '\n').encode('utf-8'))
    tn.read_until('#'.encode('utf-8'))
    tn.write(('cat /sys/class/thermal/thermal_zone0/temp'+'\n').encode('utf-8'))
    tn.read_until('\n'.encode('utf-8'))
    temp = tn.read_until('\n'.encode('utf-8'))
    temp_i = int(temp[:5])
    temp_i = round(temp_i/1000)
    output = '{"temperature": ' + str(temp_i) + '}'
    tn.close()
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return output

其中 Host 是路由器的局域网 IP 地址,username 是 Telnet 的用户名,password 是 Telnet 的密码。
脚本中有很多小细节是针对路由器写的。如果你的路由器不是 AC86U ,那么这个脚本很可能不能正常运作。有编程基础的读者可以自行针对路由器修改。

配置服务器

我的树莓派已经装好了 Apache 2 和 Python 3.5。为了让 Apache 运行 Python 脚本,需要安装 WSGI 模块:

sudo apt-get install libapache2-mod-wsgi
sudo apt-get install libapache2-mod-wsgi-py3

WSGI 安装完成后默认是启用 WSGI 模块的。为了确保正常运行,可以看下 /etc/apache2/mods-enabled 目录下有没有 wsgi.confwsgi.load。如果没有,从 mods-availableln -scp 到 mods-enabled 目录下。

脚本我放在 /var/www/homebridge 下,你也可以选择不同的目录,在配置服务器的时候更改相应目录即可。

现在配置服务器,让服务器能执行我的脚本。

vim /etc/apache2/apache2.conf

首先要给 /var/www/homebridge 赋予权限:

<Directory /var/www/homebridge/>
    AllowOverride None
    Options +ExecCGI
    Require all granted
</Directory>

然后链接服务器访问地址和脚本文件:

WSGIScriptAlias /homebridge/cputemp /var/www/homebridge/cputemp.wsgi
WSGIScriptAlias /homebridge/2.4G_temp /var/www/homebridge/2.4G_temp.wsgi
WSGIScriptAlias /homebridge/5G_temp /var/www/homebridge/5G_temp.wsgi

可以看到在 /var/www/homebridge 下,脚本文件名分别是 cputemp.wsgi2.4G_temp.wsgi5G_temp.wsgi
添加完成以上内容之后,我把这几个脚本写好放入 /var/www/homebridge,重启 Apache:

service apache2 restart

为了可行,可以先用手机或电脑浏览器访问树莓派,查看服务器是否能返回正确的 json。到此服务器和脚本就已经配置完成了。

Homebridge 配置插件

如上文所述,Homebridge 插件配置非常简单,只需在 config.json 中添加内容即可。
accessories 对象下内容:

"accessories":[
        {
                "accessory": "MiAirPurifier",
                "name": "Air Purifier",
                "ip": "192.168.1.8",
                "token": "6f7a65786550386c700a6b526666744d",
                "showTemperature": true,
                "showHumidity": true,
                "showAirQuality": true,
                "showLED": true,
                "showBuzzer": true
        },
        {
                "accessory": "HttpTemphum",
                "name": "AC86U CPU Temperature",
                "url": "http://localhost/homebridge/cputemp",
                "httpMethod": "GET",
                "humidity": false,
                "cacheExpiration": 60
        },
        {
                "accessory": "HttpTemphum",
                "name": "AC86U 2.4G Model Temperature",
                "url": "http://localhost/homebridge/2.4G_temp",
                "httpMethod": "GET",
                "humidity": false,
                "cacheExpiration": 60
        },
        {
                "accessory": "HttpTemphum",
                "name": "AC86U 5G Model Temperature",
                "url": "http://localhost/homebridge/5G_temp",
                "httpMethod": "GET",
                "humidity": false,
                "cacheExpiration": 60
        }
]

accessory 值为 HttpTemphum 的对象中有以下几个键值对:
name :传感器名称,可更改。
url :服务器访问地址。在这里 Homebridge 和服务器均为树莓派,所以可以用 localhost 代替 IP 地址。
httpMethod :HTTP 请求方式,填 GET
humidity :是否显示湿度,这里填 false
cacheExpiration :数据的存储周期,单位:秒。如果不清楚这个键值的作用,填 60 即可。

到这里之后有一个关键步骤,否则会出现配件无响应,或者重新连接家庭应用的时候,提示要重置配件。
在每次更改 config.json 并使更改生效前,需要清理 ~/.homebridge 下除了 config.json 的其他文件,这里需要清理的文件有两个文件夹: accessoriespersist

cd ~/.homebridge
rm -rf accessories persist

删除之后重新启动树莓派:

sudo reboot

按照上文的配对步骤,让 iPhone 重新配对一下即可。

后记

这篇文章编写前,我对这个 Homekit 是垂涎已久,网上也有不少教程,但有的细节没有给出,导致实现过程磕磕绊绊,花了不少时间。所以想写一篇文章,不仅仅是记录这个实现的过程,也是为了更多人能花更少的时间,走更少弯路。第一次写博客,不足之处敬请谅解,若有错误请指正,或有不够详尽之处请指出。

参考链接:
Node.js 安装:https://www.runoob.com/nodejs/nodejs-install-setup.html
Homebridge GitHub :https://github.com/nfarina/homebridge
homebridge-mi-air-purifier 插件 GitHub :https://github.com/seikan/homebridge-mi-air-purifier
homebridge-http-temperature-humidity 插件 GitHub :https://github.com/lucacri/homebridge-http-temperature-humidity
Terry’s Blog :https://blog.terrychan.me/2017/homekit-and-homebridge
华硕 AC86U 获取温度:http://www.52asus.com/thread-3819-1-1.html
WSGI Python 脚本程序:https://www.cnblogs.com/Erick-L/p/7063173.html (Apache 2 配置部分不适用)
nohup 用法:https://www.cnblogs.com/jinxiao-pu/p/9131057.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章