安装 Node.js
安装其实很简单,主要是因为要安装至少v4.3.2
的版本,所以有点麻烦
#源码安装(慢的要死)
$ wget https://nodejs.org/dist/v7.7.2/node-v7.7.2.tar.gz
$ tar xvf node-v7.7.2.tar.gz
$ cd node-v7.7.2
$ ./configure
$ make
$ make install
#命令行安装(安装出来的版本太低)
$ sudo apt-get install nodejs
$ sudo apt-get install npm
#nvm安装[install nvm](https://github.com/creationix/nvm)
$ nvm install v4.3.2
#n安装
$ npm install -g n #安装n模块(专门用来管理node.js的版本)
$ n stable #升级node.js到最新稳定版
$ n v4.3.2 #n后面也可以跟随版本号
#node常用命令
$ npm -v #显示版本,检查npm 是否正确安装。
$ npm install express #安装express模块
$ npm install -g express #全局安装express模块
$ npm list #列出已安装模块
$ npm show express #显示模块详情
$ npm update #升级当前目录下的项目的所有模块
$ npm update express #升级当前目录下的项目的指定模块
$ npm update -g express #升级全局安装的express模块
$ npm uninstall express #删除指定的模块
NanoPi上安装Node.js
安装参考 边看世界杯边安装(滑稽脸)
所有方式中只有下载官方arm包最可行,下载
node-v4.3.2-linux-armv7l.tar.gz
拷贝压缩包到NanoPi,并解压重命名为node,再拷贝至
/usr/local/bin/node
(如果之前有安装过其他版本的nodejs必须先卸载sudo apt-get remove nodejs
再删除相关文件清理干净)添加环境变量,在
/etc/profile
和~/.profile
中添加export PATH=$PATH:/usr/local/node/bin
添加链接(不添加会提示:
sudo:npm:command not found
)ln -s /usr/local/node/bin/node /usr/bin/node ln -s /usr/local/node/bin/npm /usr/bin/npm ln -s /usr/local/node/lib/node /usr/lib/node
安装结果测试
fa@NanoPi3:/usr/bin$ node -v v4.3.2 fa@NanoPi3:/usr/bin$ npm -v 2.14.12
安装 Avahi 和相关依赖软件包
$ sudo apt-get install libavahi-compat-libdnssd-dev
安装 HomeBridge 和相关依赖软件包
$ sudo npm install -g --unsafe-perm homebridge hap-nodejs node-gyp
$ cd /usr/local/lib/node_modules/homebridge/
$ sudo npm install --unsafe-perm bignum
#下面两步实测貌似没什么必要性
$ cd /usr/local/lib/node_modules/hap-nodejs/node_modules/mdns
$ sudo node-gyp BUILDTYPE=Release rebuild
Mac上安装HomeBridge
编写开关插件
整体思路:在参考代码的基础上添加一个socket,连通硬件设备,达到控制硬件的效果
- package.json
{
"name": "homebridge-pluginLight",
"version": "1.0.0",
"description": "Initial Light",
"main": "index.js",
"scripts": {
"start": "echo \"this is a light switch\" "
},
"keywords": [
"homebridge-plugin"
],
"author": "HJ",
"license": "ISC",
"engines": {
"node": ">=0.12.0",
"homebridge": ">=0.2.0"
}
}
- index.js
//增加了一个socket连接
var net = require('net');
var port = 6969;
var host = '192.168.1.143';//154
var status = false;
var client = new net.Socket();
//var Accessory, Service, Characteristic;
var Service, Characteristic;
//对外接口 供homebridge引入
module.exports = function (homebridge) {
// Accessory = homebridge.platformAccessory;
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
// registerAccessory' three parameters is plugin-name, accessory-name, constructor-name
homebridge.registerAccessory('homebridge-pluginLight', 'Plugin', PluginLight);
}
// Accessory constructor 构造函数,构建出一个对象
function PluginLight(log, config) {
this.log = log;
this.name = config['name'];
this.service = new Service.Switch(this.name); // Service.Switch means this is a plugin of Switch
this.informationService = new Service.AccessoryInformation();
//insert your Third-operation in here
//创建socket客户端
client.setEncoding('binary');
//连接到服务端
client.connect(port, host, function () {
console.log('Connect to: ' + host + ':' + port)
status = true;
});
//为客户端添加“data”事件处理函数 data是服务器发回的数据
client.on('data', function (data) {
console.log('Data: ' + data);
});
//为客户端添加“close”事件处理函数
client.on('close', function () {
console.log('Connection closed');
});
client.on('error',function(){
console.log('Server is offline');
status = false;
})
// your code ends here
this.service
.getCharacteristic(Characteristic.On)//on 表示绑定
.on('get', this.getOn.bind(this)) // get means a functon of read status
.on('set', this.setOn.bind(this)); // set means a function of set status
}
//原型加方法
PluginLight.prototype.getServices = function () {
return [this.service];
}
PluginLight.prototype.getOn = function (callback) {
console.log("**************Get on Function.**************");
callback(null);
}
PluginLight.prototype.setOn = function (value, callback) {
console.log("************** value:" + value + " **************");
if (status)
client.write(value.toString());
callback(null);
}
- config.json
{
"bridge": {
"name": "Homebridge",
"username": "94:A1:A2:BE:0B:30",
"port": 59376,
"pin": "033-73-874"
},
"description": "This is an example configuration file with one fake accessory and one fake platform. You can use this as a template for creating your own configuration file containing devices you actually own.",
"accessories": [
{
"accessory": "Plugin",
"name": "灯"
}
],
"platforms": []
}
- 运行脚本 run.sh
DEBUG=* homebridge -D -U ~/Desktop/homebridge-pluginLight/config/ -P ~/Desktop/homebridge-pluginLight/plugin/
- 硬件端
建立一个server接收homebridge的消息,调用控制舵机的脚本
#coding=utf-8
import socket
import os
server = socket.socket()
server.bind(('192.168.1.154',6969))
server.listen(5)
print("start----")
while True:
conn,addr = server.accept()
print(conn,addr)
print("*****")
while True:
data = conn.recv(1024)
if not data:
print("client has lost")
break
else:
print("data",data)
param = data.decode()
if 'false' == param:
print("false")
os.system('./pwm.sh 1135000')
else:
print("true")
os.system('./pwm.sh 2240000')
conn.send(data.upper())
server.close()
设置开机自启
- 添加守护进程文件
#$ sudo vim /etc/init.d/homebridge
#!/bin/sh
### BEGIN INIT INFO
# Provides:
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
dir="/home/fa" #!!!系统用户路径改成自己的!!!
cmd="DEBUG=* /usr/local/node/bin/homebridge -D -U /home/fa/Desktop/homebridge-pluginLight/config/ -P /home/fa/Desktop/homebridge-pluginLight/plugin/" #改成自己的运行脚本
user="fa" #!!!系统用户名改成自己的!!!
name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
cd "$dir"
if [ -z "$user" ]; then
sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
else
sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
fi
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill `get_pid`
for i in 1 2 3 4 5 6 7 8 9 10
# for i in `seq 10`
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
- 增加权限
$ sudo chmod 755 /etc/init.d/homebridge
- 手动启动
$ sudo update-rc.d homebridge defaults #系统重启后自动启动
$ sudo /etc/init.d/homebridge start #或现在手动启动
- 查看日志
$ tail -f /var/log/homebridge.log
$ tail -f /var/log/homebridge.err
说明
- 可以通过
which homebridge
查看homebridge路径;如果均按照上述步骤而未能设置成功,多半是dir cmd use
设置有误,homebridge无法正常启动,查看log解决 - 如果直接在
rc.local
中添加运行脚本,这是无法自启的(原因不明) - 如果通过运行脚本后置
&
后台运行,当关闭终端时,homebridge会自动退出(原因不明) - 猜测,可能是homebridge要实时输出log日志,关闭终端而没有给homebridge指定log输出的文件,homebridge会自动退出
- 可以通过
其他
如果从iPhone家庭终端删除了设备,想再次连接该设备时,先删除persist和accessories(homebridge自动生成的)文件,再运行homebridge