友情提示:380元/半年,儿童学编程,就上码丁实验室。


https://www.zhihu.com/video/951860902182469632
Introduction
先前做了一个利用siri或手机自带的Homekit控制LED或者继电器的实验。PI3亲测可行。遇到了些许坑,以此做一些经验总结。这个实验关键部分是利用HAP-NodeJS(Homekit辅助服务器的一种实现,也叫做homekit bridge,意思是连接将homekit代码连接wifi设备的桥梁,可以将其部署至RPI等平台),其中需要安装javascript的运行环境:node.js(说白了就是开发网页的工具);利用npm安装一系列模块:node,srp等等。
what you will need
RaspberryPI3
杜邦线
面包板
LED或者继电器
装有类似Homekit的APP的手机,我也试了一下eve可以用,如果要用到siri的话,就需要iphone了。
What you will do
- 先将树莓派装好系统,最新版的即可,我之前试了几次未成功以为要装回原来的就系统,后来试了之后才发现没有必要。
- 用putty连上Rpi
- 安装模块: sudo apt-get install npm git-core libnss-mdns libavahi-compat-libdnssd-dev
- 安装新版的nodejs:如果尝试使用apt-get来安装的话,你会发现版本太老导致无法使用,这里需要使用到wget从网上下载linux版本安装。在这里卡住了几次,可以先去一下官网了解一下版本信息: http://nodejs.org至 download/release/latest-v5.x.0/.
wget https://nodejs.org/download/release/latest-v5.x.0/node-v5.5.0-linux-armv7l.tar.gz
tar -xvf node-v5.5.0-linux-armv7l.tar.gz
cd node-v5.5.0-linux-armv7l
sudo cp -R * /usr/local
安装成功后检查下版本是否更新:
node version
安装node模块,npm全称为 Node Package Manager:
sudo npm install -g npm
sudo npm install -g node-gyp
5. 最后配置HAP-Nodejs:
git clone https://github.com/KhaosT/HAP-NodeJS.git
cd HAP-NodeJS
npm rebuild
sudo npm install node-persist
sudo npm install srp
sudo npm install mdns --unsafe-perm
sudo npm install debug
sudo npm install ed25519 --unsafe-perm
sudo npm install curve25519 --unsafe-perm
中途可能会遇到安装error出现有点烦,但是他会告诉你是哪个模块缺失之类的,所以针对这些缺少的模块再安装(sudo npm install)一遍。
6. 增加新的灯泡辅件,在HAP-NodeJS文件夹下面找到 accessories,里面已经有了一些.js文件,这些文件时javascript代码,你也可以新建一个你需要命名的设备:
cd accessories
nano myLight_accessory.js
将一些代码复制至.js文件,light0和light1是python代码分别用来控制gpio的on和off:
var PythonShell = require('python-shell');
// HomeKit types required
var types = require("./types.js")
var exports = module.exports = {};
var execute = function(accessory,characteristic,value){ console.log("executed accessory: " + accessory + ", and characteristic: " + characteristic + ", with value: " + value + "."); }
exports.accessory = {
displayName: "Light 1",
username: "1A:2B:3C:4D:5E:FF",
pincode: "031-45-154",
services: [{
sType: types.ACCESSORY_INFORMATION_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Light 1",
supportEvents: false,
supportBonjour: false,
manfDescription: "Bla",
designedMaxLength: 255
},{
cType: types.MANUFACTURER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Oltica",
supportEvents: false,
supportBonjour: false,
manfDescription: "Bla",
designedMaxLength: 255
},{
cType: types.MODEL_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Rev-1",
supportEvents: false,
supportBonjour: false,
manfDescription: "Bla",
designedMaxLength: 255
},{
cType: types.SERIAL_NUMBER_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "A1S2NASF88EW",
supportEvents: false,
supportBonjour: false,
manfDescription: "Bla",
designedMaxLength: 255
},{
cType: types.IDENTIFY_CTYPE,
onUpdate: null,
perms: ["pw"],
format: "bool",
initialValue: false,
supportEvents: false,
supportBonjour: false,
manfDescription: "Identify Accessory",
designedMaxLength: 1
}]
},{
sType: types.LIGHTBULB_STYPE,
characteristics: [{
cType: types.NAME_CTYPE,
onUpdate: null,
perms: ["pr"],
format: "string",
initialValue: "Light 1 Light Service",
supportEvents: false,
supportBonjour: false,
manfDescription: "Bla",
designedMaxLength: 255
},{
cType: types.POWER_STATE_CTYPE,
onUpdate: function(value)
{
console.log("Change:",value);
if (value) {
PythonShell.run('light1.py', function (err) {
console.log('On Success');
});
} else {
PythonShell.run('light0.py', function (err) {
console.log("Off Success");
});
}
},
perms: ["pw","pr","ev"],
format: "bool",
initialValue: false,
supportEvents: false,
supportBonjour: false,
manfDescription: "Turn On the Light",
designedMaxLength: 1
},{
cType: types.HUE_CTYPE,
onUpdate: function(value) { console.log("Change:",value); execute("Test Accessory 1", "Light - Hue", value); },
perms: ["pw","pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Doesn’t actually adjust Hue of Light",
designedMinValue: 0,
designedMaxValue: 360,
designedMinStep: 1,
unit: "arcdegrees"
},{
cType: types.BRIGHTNESS_CTYPE,
onUpdate: function(value) { console.log("Change:",value); execute("Test Accessory 1", "Light - Brightness", value); },
perms: ["pw","pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Doesn’t actually adjust Brightness of Light",
designedMinValue: 0,
designedMaxValue: 100,
designedMinStep: 1,
unit: "%"
},{
cType: types.SATURATION_CTYPE,
onUpdate: function(value) { console.log("Change:",value); execute("Test Accessory 1", "Light - Saturation", value); },
perms: ["pw","pr","ev"],
format: "int",
initialValue: 0,
supportEvents: false,
supportBonjour: false,
manfDescription: "Doesn’t actually adjust Saturation of Light",
designedMinValue: 0,
designedMaxValue: 100,
designedMinStep: 1,
unit: "%"
}]
}]
}
在HAP-NodeJS文件夹下新建一个python文件,并编写python代码:
cd ..
mkdir python
cd python
nano light1.py
python1.py控制gpio16开:
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.OUT)
GPIO.output(16, 1)
保存并关闭
nano light0.py
同样复制至light0.py:
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.OUT)
GPIO.output(16, 0)
LED接线就不解释了,进行下一步前可以先试运行下代码是否控制成功:
python light1.py
python light0.py
使用npm rebuild,最后开启Homekit Bridge:node Core.js
这里树莓派和手机需要处于同一wifi下,打开app需要输入匹配代码,即.js文件设置的pincode:

设置完成顺利的话即可点击手机控制led了,也可使用siri来语音控制。

Related
这个项目如果懂js的朋友会好玩很多.
refer to:
http://www.instructables.com/id/Raspberry-Pi-2-Homekit-from-zero-to-Hey-Siri/ https://www.makeuseof.com/tag/make-diy-siri-controlled-wi-fi-light/
HAP 安装Core.js无法启动问题:
https://github.com/KhaosT/HAP-NodeJS/issues/482
制作light_accessory.js
https://github.com/KhaosT/HAP-NodeJS/issues/191 https://docs.npmjs.com/getting-started/fixing-npm-permissions
HAP-NodeJS:
https://github.com/KhaosT/HAP-NodeJS
安装n模块 安装node最新/最稳定版本
npm install n -g
n latest/stable

http://weixin.qq.com/r/Nyj_5kPEph7ZrQeF930l (二维码自动识别)
始发于知乎专栏:teddy