如何開發(fā)homebridge插件

前言

本篇文章主要介紹如何為homebridge開發(fā)插件,并以一個(gè)最簡單的插件為例,對(duì)插件的結(jié)構(gòu)和調(diào)試方式進(jìn)行了講解.如果你和我一樣,使用homebridge平臺(tái)作為智能家居控制方案,并且想要根據(jù)自己的實(shí)際需要,開發(fā)新的插件或者h(yuǎn)ack已有的插件,但是又找不到介紹編寫homebridge插件的文章,那么這篇文章就是你需要的了:P

貼兩張效果圖:

關(guān)閉.png
打開.png

Homebridge Log.png

Log 中有兩句Get on FunctionSe 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(鏈接)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粗梭,一起剝皮案震驚了整個(gè)濱河市火本,隨后出現(xiàn)的幾起案子雀哨,更是在濱河造成了極大的恐慌香伴,老刑警劉巖洪规,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹿响,死亡現(xiàn)場離奇詭異汗唱,居然都是意外死亡攻冷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門褥实,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呀狼,“玉大人,你說我怎么就攤上這事损离「缤В” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵僻澎,是天一觀的道長貌踏。 經(jīng)常有香客問我,道長窟勃,這世上最難降的妖魔是什么哩俭? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮拳恋,結(jié)果婚禮上凡资,老公的妹妹穿的比我還像新娘。我一直安慰自己谬运,他們只是感情好隙赁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梆暖,像睡著了一般伞访。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上轰驳,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天厚掷,我揣著相機(jī)與錄音弟灼,去河邊找鬼。 笑死冒黑,一個(gè)胖子當(dāng)著我的面吹牛田绑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抡爹,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼掩驱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冬竟?” 一聲冷哼從身側(cè)響起欧穴,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泵殴,沒想到半個(gè)月后涮帘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笑诅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年调缨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苟鸯。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖棚点,靈堂內(nèi)的尸體忽然破棺而出早处,到底是詐尸還是另有隱情,我是刑警寧澤瘫析,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布砌梆,位于F島的核電站,受9級(jí)特大地震影響贬循,放射性物質(zhì)發(fā)生泄漏咸包。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一杖虾、第九天 我趴在偏房一處隱蔽的房頂上張望烂瘫。 院中可真熱鬧,春花似錦奇适、人聲如沸坟比。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葛账。三九已至,卻和暖如春皮仁,著一層夾襖步出監(jiān)牢的瞬間籍琳,已是汗流浹背菲宴。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留趋急,地道東北人喝峦。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像宣谈,于是被迫代替她去往敵國和親愈犹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理闻丑,服務(wù)發(fā)現(xiàn)漩怎,斷路器,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,848評(píng)論 25 707
  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,708評(píng)論 0 15
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,778評(píng)論 6 342
  • 記不得從好久開始嗦嗡,在微信上寫些亂七八糟的文字勋锤,大概是堅(jiān)持更文的第19天,拿到了原創(chuàng)侥祭;便一發(fā)不可收拾叁执,像自己的孩子那...
    艾文洱閱讀 1,431評(píng)論 3 2