RPI Siri Voice Conrol

siri

视频封面

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
  1. 先将树莓派装好系统,最新版的即可,我之前试了几次未成功以为要装回原来的就系统,后来试了之后才发现没有必要。
  2. 用putty连上Rpi
  3. 安装模块: sudo apt-get install npm git-core libnss-mdns libavahi-compat-libdnssd-dev
  4. 安装新版的nodejs:如果尝试使用apt-get来安装的话,你会发现版本太老导致无法使用,这里需要使用到wget从网上下载linux版本安装。在这里卡住了几次,可以先去一下官网了解一下版本信息: 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 

ano 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

安装n模块 安装node最新/最稳定版本
npm install n -g n latest/stable
树莓派的奇幻之旅
http://weixin.qq.com/r/Nyj_5kPEph7ZrQeF930l (二维码自动识别)
 

发表评论