当今科技发展日新月异,越来越多的新兴技术步入人们生活,智能家居同样也不例外,然后人们面对新科技却望而却步,因为整套设备的价格是非常昂贵的,而且现在还没有一个厂商能提供一套完整且稳定的系统,导致现在还不能快速普及。如果你想尝尝鲜,那么,一个树莓派就能为你创建一个这样的基础环境。
安装过程比较累赘,这里就不做过多的解释了。
安装所需的库 :Node 和 HAP-NodeJS(Node版本为8.2.1,HAP-NodeJS更新为Nov 6, 2017)
打包链接:http://download.csdn.net/download/kxwinxp/10124545
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "
+----------------------------------------------------------------------
| HAP-NodeJS FOR Debian raspberry
+----------------------------------------------------------------------
| Copyright © 2017 kioye All rights reserved.
+----------------------------------------------------------------------
"
#make sure your confirm.
read -p "Do you want to install HAP-NodeJS to the $setup_path directory now?(y/n): " go;
if [ "$go" == 'n' ]||[ "$go" == 'N' ];then
exit;
fi
# get into directory of application
cd ~
mkdir application
cd application
sudo apt-get install -y git avahi-daemon avahi-discover libnss-mdns libavahi-compat-libdnssd-dev build-essential
# apt-get update --fix-missing -y
sudo service avahi-daemon start
wget -O node.tar.gz https://nodejs.org/dist/v8.2.1/node-v8.2.1-linux-armv7l.tar.xz
tar -zxvf node.tar.gz
mv node-*l usr
sudo cp -rf usr /
# install node base cross-platform
sudo npm install -g -y node-gyp
# install C++ lib
sudo apt-get install -y libavahi-compat-libdnssd-dev
# download HAP-NodeJS
git clone https://github.com/KhaosT/HAP-NodeJS.git
sudo chmod -R 777 /root ./HAP-NodeJS
# get into HAP-NodeJS directory
cd HAP-NodeJS
# install some access for HAP-NodeJS
sudo npm install -y node-persist debug mdns fast-srp-hap ed25519 buffer-shims curve25519-n2 ip python-shell
cd ..
echo "
+----------------------------------------------------------------------
| HAP-NodeJS Installed finish!!
+----------------------------------------------------------------------
| start in Bridged mode:
| sudo node HAP-NodeJS/BridgedCore.js
+----------------------------------------------------------------------
| run as an independent HomeKit device:
| sudo node HAP-NodeJS/Core.js
+----------------------------------------------------------------------
"
exit 0
sudo vim /etc/rc.local
// 在 exit 0 前添加如下:
# HAP-NodeJS 开机自启脚本(nohup为后台执行,run.log为运行记录。)
sudo nohup node /home/pi/application/HAP-NodeJS/Core.js >/home/pi/application/HAP-NodeJS/run.log 2>&1 &
# python GPIO口初始化!
python /home/pi/application/HAP-NodeJS/python/init.py
GPIO初始化口,我接下来要用的是 11、13和15口。
脚本如下:
vim ~/application/HAP-NodeJS/python/init.py
// -------------请完整复制粘贴如下内容!!------------------
#!/usr/bin/env python
import RPi.GPIO as GPIO
import sys
def setup(p):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(p, GPIO.OUT)
GPIO.setwarnings(False)
# 初始化 11、13和15口。
arr={11,13,15}
for gp in arr:
setup(gp);
sys.exit(0)
GitHub:https://github.com/KhaosT/HAP-NodeJS
HAP Nodejs是一个通过Nodejs搭建的HomeKit服务器。因此,它能直接和苹果 家庭(home)应用相连。苹果设备又支持Siri,故可以直接通过Siri控制HomeKit设备。
该配件是通过python-shell来控制GPIO,故需安装python的gpio包。
sudo apt-get install -y python-rpi.gpio
功能:控制 GPIO 13 和 15 口,分别控制灯开关和亮度(两级),默认高电平为开启。
可以直接在var powergp='13';
和var brightnessgp='15';
修改GPIO口。
// 创建MyTableLight_accessory.js
sudo vim ~/application/HAP-NodeJS/accessories/MyTableLight_accessory.js
// -------------请完整复制粘贴如下内容!!------------------
var Accessory = require('../').Accessory;
var Service = require('../').Service;
var Characteristic = require('../').Characteristic;
var uuid = require('../').uuid;
var PythonShell = require('python-shell');
var powergp='13';
var brightnessgp='15';
var LightController = {
name: "My Table Light", //name of accessory
pincode: "031-45-154",
username: "FA:3C:ED:5A:1A:1F", // MAC like address used by HomeKit to differentiate accessories.
manufacturer: "HAP-NodeJS", //manufacturer (optional)
model: "v1.0", //model (optional)
serialNumber: "A12S345KGB", //serial number (optional)
power: false, //curent power status
brightness: 100, //current brightness
hue: 0, //current hue
saturation: 0, //current saturation
outputLogs: true, //output logs
setPower: function(status) { //set power of accessory
if(this.outputLogs) {
console.log("Turning the '%s' %s", this.name, status ? "on" : "off");
}
PythonShell.run('../../home/pi/application/HAP-NodeJS/python/gpio.py', {args:[powergp+':'+(status?1:0)]}, function (err,results) {
if (err) console.log(err);
});
this.power = status;
},
getPower: function() { //get power of accessory
PythonShell.run('../../home/pi/application/HAP-NodeJS/python/gpio.py', {args:[powergp+':g']}, function(err,results){
console.log('results: %j', results);
var resultMap=eval('('+results.pop()+')');
this.power=(resultMap[powergp]==1)?true:false;
});
if(this.outputLogs) console.log("'%s' is %s.", this.name, this.power ? "on" : "off");
return this.power;
},
setBrightness: function(brightness) { //set brightness
if(this.outputLogs) console.log("Setting '%s' brightness to %s", this.name, brightness);
PythonShell.run('../../home/pi/application/HAP-NodeJS/python/gpio.py', {args:[brightnessgp+':'+((brightness <= 50)?1:0)]}, function (err,results) {
if (err) console.log(err);
});
this.brightness = brightness;
},
getBrightness: function() { //get brightness
PythonShell.run('../../home/pi/application/HAP-NodeJS/python/gpio.py', {args:[brightnessgp+':g']}, function(err,results){
console.log('results: %j', results);
var resultMap=eval('('+results.pop()+')');
this.brightness=(resultMap[brightnessgp]==1)?50:100;
});
if(this.outputLogs) console.log("'%s' brightness is %s", this.name, this.brightness);
return this.brightness;
},
setSaturation: function(saturation) { //set brightness
if(this.outputLogs) console.log("Setting '%s' saturation to %s", this.name, saturation);
this.saturation = saturation;
},
getSaturation: function() { //get brightness
if(this.outputLogs) console.log("'%s' saturation is %s", this.name, this.saturation);
return this.saturation;
},
setHue: function(hue) { //set brightness
if(this.outputLogs) console.log("Setting '%s' hue to %s", this.name, hue);
this.hue = hue;
},
getHue: function() { //get hue
if(this.outputLogs) console.log("'%s' hue is %s", this.name, this.hue);
return this.hue;
},
identify: function() { //identify the accessory
if(this.outputLogs) console.log("Identify the '%s'", this.name);
}
}
// Generate a consistent UUID for our light Accessory that will remain the same even when
// restarting our server. We use the `uuid.generate` helper function to create a deterministic
// UUID based on an arbitrary "namespace" and the word "light".
var lightUUID = uuid.generate('hap-nodejs:accessories:light' + LightController.name);
// This is the Accessory that we'll return to HAP-NodeJS that represents our light.
var lightAccessory = exports.accessory = new Accessory(LightController.name, lightUUID);
// Add properties for publishing (in case we're using Core.js and not BridgedCore.js)
lightAccessory.username = LightController.username;
lightAccessory.pincode = LightController.pincode;
// set some basic properties (these values are arbitrary and setting them is optional)
lightAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, LightController.manufacturer)
.setCharacteristic(Characteristic.Model, LightController.model)
.setCharacteristic(Characteristic.SerialNumber, LightController.serialNumber);
// listen for the "identify" event for this Accessory
lightAccessory.on('identify', function(paired, callback) {
LightController.identify();
callback();
});
// Add the actual Lightbulb Service and listen for change events from iOS.
// We can see the complete list of Services and Characteristics in `lib/gen/HomeKitTypes.js`
lightAccessory
.addService(Service.Lightbulb, LightController.name) // services exposed to the user should have "names" like "Light" for this case
.getCharacteristic(Characteristic.On)
.on('set', function(value, callback) {
LightController.setPower(value);
// Our light is synchronous - this value has been successfully set
// Invoke the callback when you finished processing the request
// If it's going to take more than 1s to finish the request, try to invoke the callback
// after getting the request instead of after finishing it. This avoids blocking other
// requests from HomeKit.
callback();
})
// We want to intercept requests for our current power state so we can query the hardware itself instead of
// allowing HAP-NodeJS to return the cached Characteristic.value.
.on('get', function(callback) {
callback(null, LightController.getPower());
});
// To inform HomeKit about changes occurred outside of HomeKit (like user physically turn on the light)
// Please use Characteristic.updateValue
//
// lightAccessory
// .getService(Service.Lightbulb)
// .getCharacteristic(Characteristic.On)
// .updateValue(true);
// also add an "optional" Characteristic for Brightness
lightAccessory
.getService(Service.Lightbulb)
.addCharacteristic(Characteristic.Brightness)
.on('set', function(value, callback) {
LightController.setBrightness(value);
callback();
})
.on('get', function(callback) {
callback(null, LightController.getBrightness());
});
// also add an "optional" Characteristic for Saturation
lightAccessory
.getService(Service.Lightbulb)
.addCharacteristic(Characteristic.Saturation)
.on('set', function(value, callback) {
LightController.setSaturation(value);
callback();
})
.on('get', function(callback) {
callback(null, LightController.getSaturation());
});
// also add an "optional" Characteristic for Hue
lightAccessory
.getService(Service.Lightbulb)
.addCharacteristic(Characteristic.Hue)
.on('set', function(value, callback) {
LightController.setHue(value);
callback();
})
.on('get', function(callback) {
callback(null, LightController.getHue());
});
sudo vim ~/application/HAP-NodeJS/python/gpio.py
// -------------请完整复制粘贴如下内容!!------------------
#!/usr/bin/env python
import RPi.GPIO as GPIO
import sys
def init(gp):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(gp, GPIO.OUT)
GPIO.setwarnings(False)
# simple argument echo script
ret={}
for arg in sys.argv[1:]:
#print arg
args=arg.split(':')
init(int(args[0]))
if args[1]=='g':
ret[args[0]]=GPIO.input(int(args[0]))
elif args[1]=='0':
GPIO.output(int(args[0]), GPIO.LOW)
elif args[1]=='1':
GPIO.output(int(args[0]), GPIO.HIGH)
#setup(int(v))
print ret
sys.exit(0)
我这个插座是接的音响,所以叫“My sound”,不要见怪。
这里使用的是 GPIO 11 口,默认是高电平是开启。
代码如下:
// 创建MySound_accessory.js
sudo vim ~/application/HAP-NodeJS/accessories/MySound_accessory.js
// -------------请完整复制粘贴如下内容!!------------------
var Accessory = require('../').Accessory;
var Service = require('../').Service;
var Characteristic = require('../').Characteristic;
var uuid = require('../').uuid;
var err = null; // in case there were any problems
var PythonShell = require('python-shell');
var soundgp='11';
// here's a fake hardware device that we'll expose to HomeKit
var FAKE_OUTLET = {
setPowerOn: function(on) {
console.log("Turning the MySound %s!...", on ? "on" : "off");
PythonShell.run('../../home/pi/application/HAP-NodeJS/python/gpio.py', {args:[soundgp+':'+(on?1:0)]}, function (err,results) {
if (err) console.log(err);
});
FAKE_OUTLET.powerOn=on;
},
identify: function() {
console.log("Identify the MySound.");
}
}
// Generate a consistent UUID for our MySound Accessory that will remain the same even when
// restarting our server. We use the `uuid.generate` helper function to create a deterministic
// UUID based on an arbitrary "namespace" and the accessory name.
var outletUUID = uuid.generate('hap-nodejs:accessories:MySound');
// This is the Accessory that we'll return to HAP-NodeJS that represents our fake light.
var outlet = exports.accessory = new Accessory('MySound', outletUUID);
// Add properties for publishing (in case we're using Core.js and not BridgedCore.js)
outlet.username = "1A:2B:3C:4D:5D:FG";
outlet.pincode = "031-45-154";
// set some basic properties (these values are arbitrary and setting them is optional)
outlet
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, "Oltica")
.setCharacteristic(Characteristic.Model, "Rev-1")
.setCharacteristic(Characteristic.SerialNumber, "A1S2NASF88EW");
// listen for the "identify" event for this Accessory
outlet.on('identify', function(paired, callback) {
FAKE_OUTLET.identify();
callback(); // success
});
// Add the actual MySound Service and listen for change events from iOS.
// We can see the complete list of Services and Characteristics in `lib/gen/HomeKitTypes.js`
outlet
.addService(Service.Outlet, "My Sound") // services exposed to the user should have "names" like "Fake Light" for us
.getCharacteristic(Characteristic.On)
.on('set', function(value, callback) {
FAKE_OUTLET.setPowerOn(value);
callback(); // Our fake Outlet is synchronous - this value has been successfully set
});
// We want to intercept requests for our current power state so we can query the hardware itself instead of
// allowing HAP-NodeJS to return the cached Characteristic.value.
outlet
.getService(Service.Outlet)
.getCharacteristic(Characteristic.On)
.on('get', function(callback) {
// this event is emitted when you ask Siri directly whether your light is on or not. you might query
// the light hardware itself to find this out, then call the callback. But if you take longer than a
// few seconds to respond, Siri will give up.
var err = null; // in case there were any problems
if (FAKE_OUTLET.powerOn) {
console.log("Are we on? Yes.");
callback(err, true);
}
else {
console.log("Are we on? No.");
callback(err, false);
}
});
控制也是通过调用 gpio.py 的 python 脚本,和 4.1 里面的 python 脚本一样的。
好了,现在可以重启一下树莓派。
如图,选择将这些设备添加进去,输入认证代码
03145154
(这个可以在accessary.js修改)。
然后就可以愉快使用 Siri 进行语音控制了!