跳转至

HomeBridge

概述

  HomeBridge是一个模拟iOS HomeKit API轻量级的Node.js服务器,可以实现从智能家居设备制造商的各种三方API到iOS HomeKit的桥接。由于Siri支持HomeKit设备的操作,这意味着通过Homebridge,你可以用Siri控制不支持HomeKit的设备。

例如,你可以说:

  • Hey Siri,打开后门。
  • Hey Siri,打开车库门。
  • Hey Siri,打开咖啡机。
  • Hey Siri,打开客厅的灯。
  • Hey Siri,早上好!

可以通过搜索关键字homebridge-plugin在NPM网站上找到可用插件。

安装

1.确认Node.js环境

确定你的机器Node.js安装没有问题,可通过如下命令检测:

node -v
npm -v
示例如下:
pi@raspberrypi:~$ 
pi@raspberrypi:~$ node -v
v7.10.1
pi@raspberrypi:~$ npm -v
4.2.0
pi@raspberrypi:~$ 
若可以返回版本号,即可操作下一步。

注:HomeBridge描述文件中,要求使用Node.js版本号大于4.3.2。但有些插件可能使用高版本的功能,个人建议使用7.x或更高版本。

2.安装HomeBridge

通过NPM安装HomeBridge,命令如下:

sudo npm install -g --unsafe-perm homebridge
示例如下:
pi@raspberrypi:~$
pi@raspberrypi:~$ sudo npm install -g --unsafe-perm homebridge
/usr/local/bin/homebridge -> /usr/local/lib/node_modules/homebridge/bin/homebridge

> mdns@2.3.4 install /usr/local/lib/node_modules/homebridge/node_modules/mdns
> node-gyp rebuild

make: Entering directory '/usr/local/lib/node_modules/homebridge/node_modules/mdns/build'
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_sd.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_browse.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_enumerate_domains.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_get_addr_info.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_process_result.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref_deallocate.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref_sock_fd.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_register.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_resolve.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_update_record.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/mdns_utils.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/network_interface.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/socket_watcher.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_ref.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_create.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_deallocate.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_set_value.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_get_length.o
  CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_buffer_to_object.o
  SOLINK_MODULE(target) Release/obj.target/dns_sd_bindings.node
  COPY Release/dns_sd_bindings.node
make: Leaving directory '/usr/local/lib/node_modules/homebridge/node_modules/mdns/build'

> curve25519-n2@1.1.3 install /usr/local/lib/node_modules/homebridge/node_modules/curve25519-n2
> node-gyp rebuild

make: Entering directory '/usr/local/lib/node_modules/homebridge/node_modules/curve25519-n2/build'
  CXX(target) Release/obj.target/curve/node_curve.o
  SOLINK_MODULE(target) Release/obj.target/curve.node
  COPY Release/curve.node
make: Leaving directory '/usr/local/lib/node_modules/homebridge/node_modules/curve25519-n2/build'

> ed25519@0.0.4 install /usr/local/lib/node_modules/homebridge/node_modules/ed25519
> node-gyp rebuild

make: Entering directory '/usr/local/lib/node_modules/homebridge/node_modules/ed25519/build'
  CC(target) Release/obj.target/ed25519/src/ed25519/keypair.o
  CC(target) Release/obj.target/ed25519/src/ed25519/sign.o
  CC(target) Release/obj.target/ed25519/src/ed25519/open.o
  CC(target) Release/obj.target/ed25519/src/ed25519/crypto_verify_32.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_double_scalarmult.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_frombytes.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_scalarmult_base.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_precomp_0.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p2_0.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p2_dbl.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p3_0.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p3_dbl.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p3_to_p2.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p3_to_cached.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p3_tobytes.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_madd.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_add.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_msub.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_sub.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p1p1_to_p3.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_p1p1_to_p2.o
  CC(target) Release/obj.target/ed25519/src/ed25519/ge_tobytes.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_0.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_1.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_cmov.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_copy.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_neg.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_add.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_sub.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_mul.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_sq.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_sq2.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_invert.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_tobytes.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_isnegative.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_isnonzero.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_frombytes.o
  CC(target) Release/obj.target/ed25519/src/ed25519/fe_pow22523.o
  CC(target) Release/obj.target/ed25519/src/ed25519/sc_reduce.o
  CC(target) Release/obj.target/ed25519/src/ed25519/sc_muladd.o
  CXX(target) Release/obj.target/ed25519/src/ed25519.o
  SOLINK_MODULE(target) Release/obj.target/ed25519.node
  COPY Release/ed25519.node
make: Leaving directory '/usr/local/lib/node_modules/homebridge/node_modules/ed25519/build'
/usr/local/lib
└─┬ homebridge@0.4.33 
  ├─┬ chalk@1.1.3 
  │ ├── ansi-styles@2.2.1 
  │ ├── escape-string-regexp@1.0.5 
  │ ├─┬ has-ansi@2.0.0 
  │ │ └── ansi-regex@2.1.1 
  │ ├── strip-ansi@3.0.1 
  │ └── supports-color@2.0.0 
  ├─┬ commander@2.8.1 
  │ └── graceful-readlink@1.0.1 
  ├─┬ hap-nodejs@0.4.36 
  │ ├── buffer-shims@1.0.0 
  │ ├─┬ curve25519-n2@1.1.3 
  │ │ ├── bindings@1.2.1 
  │ │ └── nan@2.8.0 
  │ ├─┬ debug@2.6.9 
  │ │ └── ms@2.0.0 
  │ ├── decimal.js@7.5.1 
  │ ├── ed25519@0.0.4 
  │ ├── fast-srp-hap@1.0.1 
  │ ├── ip@1.1.5 
  │ ├─┬ mdns@2.3.4 
  │ │ └── nan@2.3.5 
  │ └─┬ node-persist@0.0.11 
  │   └─┬ mkdirp@0.5.1 
  │     └── minimist@0.0.8 
  ├─┬ node-persist@0.0.8 
  │ ├── mkdirp@0.3.5 
  │ └── q@1.1.2 
  ├── qrcode-terminal@0.11.0 
  └── semver@5.0.3 

pi@raspberrypi:~$

3.确认HomeBridge

检测HomeBridge是否安装成功,执行如下命令:

homebridge --version
示例如下:
pi@raspberrypi:~$ 
pi@raspberrypi:~$ homebridge --version
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
0.4.33
pi@raspberrypi:~$ 
若能正确显示HomeBridge版本,即表示HomeBridge安装成功。

配置

默认情况下,HomeBridge会使用用户目录下的.homebridge文件夹作为用户存储路径,即~/.homebridge/目录。 若不存在,可通过如下命令建立:

mkdir ~/.homebridge/
进入~/.homebridge/目录,创建配置文件config.json,命令如下:
cd ~/.homebridge/
nano config.json
示例如下:
pi@raspberrypi:~$ 
pi@raspberrypi:~$ mkdir ~/.homebridge/
pi@raspberrypi:~$ cd ~/.homebridge/
pi@raspberrypi:~/.homebridge$ nano config.json
将如下内容键入到文件中:
{
    "bridge": {
        "name": "HomeBridge",    
        "username": "00:00:00:00:00:01",
        "port": 58881,
        "pin": "111-00-001"
    },
    "accessories": [
    ],
    "platforms": [
    ]
}
使用Ctrl+O将内容保存到文件中,使用Ctrl+X退出nano文本编辑器。

注:一个HomeBridge配置中,只能存在一个accessories和platforms。

启动

1.正常启动

键入如下命令启动HomeBridge。

homebridge
示例如下:
pi@raspberrypi:~/.homebridge$ homebridge
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
[1/1/2018, 5:39:37 PM] No plugins found. See the README for information on installing plugins.
[1/1/2018, 5:39:37 PM] Loaded config.json with 0 accessories and 0 platforms.
[1/1/2018, 5:39:37 PM] ---
[1/1/2018, 5:39:37 PM] Loading 0 platforms...
[1/1/2018, 5:39:37 PM] Loading 0 accessories...
Setup Payload:
X-HM://0023NJGWXLMEC
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:

    ┌────────────┐     
    │ 111-00-001 │     
    └────────────┘     

[1/1/2018, 5:39:37 PM] Homebridge is running on port 58881.

2.Debug方式启动

键入如下命令启动HomeBridge。

homebridge -D

3.后台启动及关闭

键入如下命令后台启动HomeBridge。

nohup homebridge > ~/homebridge.log 2>&1 &
注:~/homebridge.log为后台启动日志文件位置,可改成其它路径。若不想保留日志可指向/dev/null。

键入如下命令查找后台启动的HomeBridge的进程ID:

ps -eaf | grep homebridge | grep -v grep
键入如下命令关闭后台启动的HomeBridge:
kill -9 HomeBridge的进程ID
示例代码:
pi@raspberrypi:~$ 
pi@raspberrypi:~$ nohup homebridge > /dev/null 2>&1 &
[1] 14528
pi@raspberrypi:~$ 
pi@raspberrypi:~$ ps -eaf | grep homebridge | grep -v grep
pi       14528 14477 14 23:15 pts/0    00:00:01 homebridge
pi@raspberrypi:~$ kill -9 14528
[1]+  Killed                  nohup homebridge > /dev/null 2>&1
pi@raspberrypi:~$ 

启动参数说明

HomeBridge目前(0.4.33)支持如下启动参数:

注:字母区分大小写。

参数 参数(或) 格式 说明
-h --help homebridge -h 查看HomeBridge使用帮助
-V --version homebridge -V 查看HomeBridge版本
-P --plugin-path homebridge -P [path] 指定HomeBridge载入的插件位置
-U --user-storage-path homebridge -U [path] 指定HomeBridge载入的用户存储路径位置
-D --debug homebridge -D 开启调试模式
-I --insecure homebridge -I 允许非授权请求

示例如下:

pi@raspberrypi:~/.homebridge$ 
pi@raspberrypi:~/.homebridge$ homebridge -h
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>

  Usage: homebridge [options]

  Options:

    -h, --help                      output usage information
    -V, --version                   output the version number
    -P, --plugin-path [path]        look for plugins installed at [path] as well as the default locations ([path] can also point to a single plugin)
    -U, --user-storage-path [path]  look for homebridge user files at [path] instead of the default location (~/.homebridge)
    -D, --debug                     turn on debug level logging
    -I, --insecure                  allow unauthenticated requests (for easier hacking)

pi@raspberrypi:~/.homebridge$ 

开机自启

编辑/etc/rc.local文件,命令如下:

sudo nano /etc/rc.local
在文件最后exit 0上添加如下语句:
sudo -i -u pi nohup homebridge > ~/homebridge.log 2>&1 &
使用Ctrl+O将内容保存到文件中,使用Ctrl+X退出nano文本编辑器。

注:该方法必须使用后台启动HomeBridge的方式启动。

注:本例中使用pi作为启动用户,请视自己情况更改用户名。

/etc/rc.local文件示例如下:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

sudo -i -u pi nohup homebridge > ~/homebridge.log 2>&1 &

exit 0

清除配件添加信息

  1. 关闭HomeBridge。
  2. 进入用户存储路径,删除persist文件夹。 示例如下:
    pi@raspberrypi:~$ 
    pi@raspberrypi:~$ cd /home/pi/.homebridge/
    pi@raspberrypi:~/.homebridge$ ll
    total 20
    drwxr-xr-x  4 pi pi 4096 Jan  1 17:39 .
    drwxr-xr-x 16 pi pi 4096 Jan  2 23:10 ..
    drwxr-xr-x  2 pi pi 4096 Jan  1 17:41 accessories
    -rw-r--r--  1 pi pi  202 Jan  1 17:37 config.json
    drwxr-xr-x  2 pi pi 4096 Jan  1 17:39 persist
    pi@raspberrypi:~/.homebridge$ rm -rf persist/
    pi@raspberrypi:~/.homebridge$ 
    
    注:执行清除配件添加信息操作切记关闭HomeBridge。

清除配件缓存信息

  1. 关闭HomeBridge。
  2. 进入用户存储路径,删除accessories文件夹。 示例如下:
    pi@raspberrypi:~$ 
    pi@raspberrypi:~$ cd /home/pi/.homebridge/
    pi@raspberrypi:~/.homebridge$ ll
    total 20
    drwxr-xr-x  4 pi pi 4096 Jan  1 17:39 .
    drwxr-xr-x 16 pi pi 4096 Jan  2 23:10 ..
    drwxr-xr-x  2 pi pi 4096 Jan  1 17:41 accessories
    -rw-r--r--  1 pi pi  202 Jan  1 17:37 config.json
    drwxr-xr-x  2 pi pi 4096 Jan  1 17:39 persist
    pi@raspberrypi:~/.homebridge$ rm -rf accessories/
    pi@raspberrypi:~/.homebridge$ 
    
    注:执行清除配件缓存信息操作切记关闭HomeBridge。

常见问题

  1. 已经启动HomeBridge,但是无法搜索到桥配件。
    可能原因:HomeBridge配件已被其它AppleID添加。
    解决方案:关闭HomeBridge,清除配件添加信息。
    注:在HomeKit中删除配件操作一定要在HomeBridge启动时执行。若HomeBridge处于关闭状态时删除了配件,HomeBridge并不之情配件被删除,因此HomeBridge还会认为自己是被AppleID添加了的状态,所以无法再次被搜索到。

  2. 启动HomeBridge时报错SyntaxError: Unexpected token, in JSON at position xxx
    可能原因:HomeBridge的配置文件编写错误。
    解决方案:检查HomeBridge配置文件config.json的正确性,着重注意第xxx行。可参考JSON

  3. 启动HomeBridge时报错Error: listen EADDRINUSE :::xxxxx
    可能原因:HomeBridge所使用的端口被占用。
    解决方案:检查HomeBridge所使用的端口是否被其它程序占用,若占用则修改HomeBridge配置文件使用其它端口,若未被占用那么极有可能是已经启动了一个HomeBridge程序。可通过ps -eaf | grep homebridge | grep -v grep命令找到已经启动的HomeBridge程序的进程ID,并使用kill -9 HomeBridge的进程ID命令关闭已启动的HomeBridge程序。

  4. 启动HomeBridge时报错Error: The requested platform 'xxxxxx' was not registered by any plugin.
    可能原因:xxxxxx配件没有被安装,但是HomeBridge配置中却写了该配件。
    解决方案:安装xxxxxx配件。

更多信息

项目GitHub地址:https://github.com/nfarina/homebridge