使用Siri通过HomeBrige关灯

安装 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

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

参考链接

猜你喜欢

转载自blog.csdn.net/robothj/article/details/80717714