前言
本篇文章主要介紹如何為homebridge開發(fā)插件,并以一個(gè)最簡單的插件為例,對(duì)插件的結(jié)構(gòu)和調(diào)試方式進(jìn)行了講解.如果你和我一樣,使用homebridge平臺(tái)作為智能家居控制方案,并且想要根據(jù)自己的實(shí)際需要,開發(fā)新的插件或者h(yuǎn)ack已有的插件,但是又找不到介紹編寫homebridge插件的文章,那么這篇文章就是你需要的了:P
貼兩張效果圖:
Log 中有兩句
Get on Function
和Se ton Function
分別是我在插件中自己添加的log打印.
1. 開發(fā)環(huán)境
- 一個(gè)homebridge環(huán)境,不安裝任何插件
- 一部iOS設(shè)備
2. 待開發(fā)的插件包
先說一下目錄結(jié)構(gòu),下面的文章基于這個(gè)目錄結(jié)構(gòu):
~/piDire/homebridge-dev$ tree
.
├── config
│ └── config.json
├── plugin
│ ├── index.js
│ └── package.json
└── README.md
本地初始化一個(gè)Node項(xiàng)目
首先,在頭腦中給插件起一個(gè)名字,比如叫做homebridge-plugintest
.你也可以叫其他名字,但是一定要以homebridge-
前綴開頭,因?yàn)閔omebridge在搜索插件時(shí)會(huì)默認(rèn)以homebridge-
前綴搜索,如果你的插件不帶有這個(gè)前綴的話,就無法被homebridge
識(shí)別到.然后本地建立一個(gè)文件夾,文件夾名字隨意起,我的叫做plugin
切換到文件夾路徑下運(yùn)行npm init
,自動(dòng)生成package.json
文件,生成文件時(shí)會(huì)要求輸入包的名字,這里要和插件的名字一致,也叫homebridge-plugintest
.因?yàn)槲覀兊?code>homebridge插件其實(shí)也就是一個(gè)npm包,要符合npm的插件規(guī)范.之后在這個(gè)路徑下新建index.js
文件,在index.js
中編寫插件框架代碼.編輯代碼
這里主要指index.js文件中的插件框架代碼.homebridge的插件是有一套固定框架的,我們主要根據(jù)自己的插件功能實(shí)現(xiàn)其中的一部分函數(shù)即可.
框架關(guān)鍵代碼批注1:
module.exports = function(homebridge) {
// Accessory = homebridge.platformAccessory;
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
// registerAccessory' 的三個(gè)參數(shù)分別是 plugin-name, accessory-name, constructor-name
homebridge.registerAccessory('homebridge-pluginTest', 'Plugin', PluginTest);
}
分別解釋一下,plugin-name就是插件的名字,前面已經(jīng)起好了,和package.json中的插件名一樣;accessory-name是在config.json中要用到的Accessory名字,只要記住這里要和config.json保持一致就好了;最后一個(gè)是構(gòu)造函數(shù)的名字,這個(gè)的作用我也不是很清楚,不過要和下面的class的名稱保持一致.
框架關(guān)鍵代碼批注2:
// Accessory constructor
function PluginTest(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 own-operation in here
// your code ends here
this.service
.getCharacteristic(Characteristic.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
}
這里上面的幾行表示從config.json配置文件中讀取用戶設(shè)置的配置,比如調(diào)用的Accessory名稱和使用的pin管腳數(shù).其中的一行this.service=new Service.Switch()
這一句代表了這個(gè)插件是一個(gè)Switch類型,即開關(guān)類型的插件.換句話說,這一句決定了你的插件在iOS上面的顯示方式,是顯示為一個(gè)開關(guān)還是顯示為一個(gè)風(fēng)扇還是顯示為一個(gè)溫度濕度值.因此,在確定你的插件的類型之后,我的建議是先在github上面搜索同類型的插件,然后看一下前輩們的插件中這里使用的是什么Service,來確定這種類型的插件應(yīng)該使用什么Service.
最下面的一句我覺得應(yīng)該是設(shè)置回調(diào)函數(shù),就是當(dāng)用戶點(diǎn)擊界面時(shí),homebridge應(yīng)該調(diào)用哪個(gè)函數(shù)來響應(yīng)用戶的操作.
框架關(guān)鍵代碼批注3:
PluginTest.prototype.getServices = function() {
return [this.service];
}
這一句我也不太懂是什么作用,就先當(dāng)做是框架的固定格式吧.
添加調(diào)試用的config.json
編寫完插件之后,需要在config.json文件中為插件補(bǔ)充對(duì)應(yīng)的配件定義.事實(shí)上,我建議單獨(dú)新建一個(gè)config.json文件,作為我們調(diào)試專用的config.我自己的實(shí)現(xiàn)方式是,新建一個(gè)文件夾,然后在文件夾下新建一個(gè)config.json,json文件中的定義需要和插件中的配置名稱保持一致.比如,下面是我調(diào)試用的config.json文件:
{
"bridge": {
"name": "Homebridge",
"username": "CC:22:3D:E3:CE:50",
"port": 55373,
"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": "Coffee Maker"
}
],
"platforms": []
}
和其他插件的config.json文件對(duì)比一下可以發(fā)現(xiàn),上面bridge
部分的定義相同,具體下面的accessories
部分是我們需要根據(jù)插件內(nèi)容定義的地方.結(jié)合我上面的框架關(guān)鍵代碼1和2部分解釋一下:
config.json文件中有accessory
字段,homebridge根據(jù)這個(gè)字段的值來確定這部分accessory配置是給哪個(gè)插件來用的,因此這個(gè)字段的名稱要和我們框架關(guān)鍵代碼1部分中的registerAccessory
部分第二個(gè)參數(shù)保持一致.以此來告訴homebridge,這個(gè)accessory
部分的配置是給homebridge-plugintest插件寫的,那么下面config下面部分的name
字段就可以和框架關(guān)鍵代碼2中的this.name
字段匹配上.由此你也應(yīng)該可以推斷出,平時(shí)你使用的那些插件中的config.json文件里定義的那些東西的含義了吧.比如我之前用過一個(gè)homebridge-gpio-wpi插件,它的配置文件中就有一個(gè)'pin'字段,對(duì)應(yīng)待插件代碼中一定有一個(gè)this.pin
字段去讀取,進(jìn)而進(jìn)行操作.如果你有興趣,也可以在自己的插件中加上一個(gè)pin
字段試一下:)
- 在開發(fā)環(huán)境上安裝,迭代開發(fā)
本地調(diào)試插件命令
DEBUG=* homebridge -D -U ~/homebridge-dev/config/ -P ~/homebridge-dev/plugin/
其中/homebridge-dev
下面存放本地的調(diào)試用config.json文件,/plugin
下面為插件的開發(fā)目錄,一般包含package和index.js文件.
最后給出我的插件代碼的github地址homebridge-sampleplugin,你可以直接clone下來,自己運(yùn)行一下,一定要按照我上面寫的目錄結(jié)構(gòu)放置文件.
遇到的坑
-
坑1
錯(cuò)誤關(guān)鍵詞:
[11/14/2017, 9:19:05 PM] Error: Plugin /home/pi/plugin does not contain the 'homebridge' package in 'engines'.
出現(xiàn)這個(gè)錯(cuò)誤的原因是自動(dòng)生成的package.json不滿足homebridge的要求,缺少一個(gè)engine字段,需要我們手動(dòng)補(bǔ)充上
"engines": {
"node": ">=0.12.0",
"homebridge": ">=0.2.0"
}
解決方法來自Google(鏈接)