前言
本篇文章主要介绍如何为homebridge开发插件,并以一个最简单的插件为例,对插件的结构和调试方式进行了讲解.如果你和我一样,使用homebridge平台作为智能家居控制方案,并且想要根据自己的实际需要,开发新的插件或者hack已有的插件,但是又找不到介绍编写homebridge插件的文章,那么这篇文章就是你需要的了:P
贴两张效果图:
Log 中有两句
Get on Function
和Se ton Function
分别是我在插件中自己添加的log打印.
1. 开发环境
- 一个homebridge环境,不安装任何插件
- 一部iOS设备
2. 待开发的插件包
先说一下目录结构,下面的文章基于这个目录结构:
~/piDire/homebridge-dev$ tree
.
├── config
│ └── config.json
├── plugin
│ ├── index.js
│ └── package.json
└── README.md
本地初始化一个Node项目
首先,在头脑中给插件起一个名字,比如叫做homebridge-plugintest
.你也可以叫其他名字,但是一定要以homebridge-
前缀开头,因为homebridge在搜索插件时会默认以homebridge-
前缀搜索,如果你的插件不带有这个前缀的话,就无法被homebridge
识别到.然后本地建立一个文件夹,文件夹名字随意起,我的叫做plugin
切换到文件夹路径下运行npm init
,自动生成package.json
文件,生成文件时会要求输入包的名字,这里要和插件的名字一致,也叫homebridge-plugintest
.因为我们的homebridge
插件其实也就是一个npm包,要符合npm的插件规范.之后在这个路径下新建index.js
文件,在index.js
中编写插件框架代码.编辑代码
这里主要指index.js文件中的插件框架代码.homebridge的插件是有一套固定框架的,我们主要根据自己的插件功能实现其中的一部分函数即可.
框架关键代码批注1:
module.exports = function(homebridge) {
// Accessory = homebridge.platformAccessory;
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
// registerAccessory' 的三个参数分别是 plugin-name, accessory-name, constructor-name
homebridge.registerAccessory('homebridge-pluginTest', 'Plugin', PluginTest);
}
分别解释一下,plugin-name就是插件的名字,前面已经起好了,和package.json中的插件名一样;accessory-name是在config.json中要用到的Accessory名字,只要记住这里要和config.json保持一致就好了;最后一个是构造函数的名字,这个的作用我也不是很清楚,不过要和下面的class的名称保持一致.
框架关键代码批注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配置文件中读取用户设置的配置,比如调用的Accessory名称和使用的pin管脚数.其中的一行this.service=new Service.Switch()
这一句代表了这个插件是一个Switch类型,即开关类型的插件.换句话说,这一句决定了你的插件在iOS上面的显示方式,是显示为一个开关还是显示为一个风扇还是显示为一个温度湿度值.因此,在确定你的插件的类型之后,我的建议是先在github上面搜索同类型的插件,然后看一下前辈们的插件中这里使用的是什么Service,来确定这种类型的插件应该使用什么Service.
最下面的一句我觉得应该是设置回调函数,就是当用户点击界面时,homebridge应该调用哪个函数来响应用户的操作.
框架关键代码批注3:
PluginTest.prototype.getServices = function() {
return [this.service];
}
这一句我也不太懂是什么作用,就先当做是框架的固定格式吧.
添加调试用的config.json
编写完插件之后,需要在config.json文件中为插件补充对应的配件定义.事实上,我建议单独新建一个config.json文件,作为我们调试专用的config.我自己的实现方式是,新建一个文件夹,然后在文件夹下新建一个config.json,json文件中的定义需要和插件中的配置名称保持一致.比如,下面是我调试用的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文件对比一下可以发现,上面bridge
部分的定义相同,具体下面的accessories
部分是我们需要根据插件内容定义的地方.结合我上面的框架关键代码1和2部分解释一下:
config.json文件中有accessory
字段,homebridge根据这个字段的值来确定这部分accessory配置是给哪个插件来用的,因此这个字段的名称要和我们框架关键代码1部分中的registerAccessory
部分第二个参数保持一致.以此来告诉homebridge,这个accessory
部分的配置是给homebridge-plugintest插件写的,那么下面config下面部分的name
字段就可以和框架关键代码2中的this.name
字段匹配上.由此你也应该可以推断出,平时你使用的那些插件中的config.json文件里定义的那些东西的含义了吧.比如我之前用过一个homebridge-gpio-wpi插件,它的配置文件中就有一个'pin'字段,对应待插件代码中一定有一个this.pin
字段去读取,进而进行操作.如果你有兴趣,也可以在自己的插件中加上一个pin
字段试一下:)
- 在开发环境上安装,迭代开发
本地调试插件命令
DEBUG=* homebridge -D -U ~/homebridge-dev/config/ -P ~/homebridge-dev/plugin/
其中/homebridge-dev
下面存放本地的调试用config.json文件,/plugin
下面为插件的开发目录,一般包含package和index.js文件.
最后给出我的插件代码的github地址homebridge-sampleplugin,你可以直接clone下来,自己运行一下,一定要按照我上面写的目录结构放置文件.
遇到的坑
-
坑1
错误关键词:
[11/14/2017, 9:19:05 PM] Error: Plugin /home/pi/plugin does not contain the 'homebridge' package in 'engines'.
出现这个错误的原因是自动生成的package.json不满足homebridge的要求,缺少一个engine字段,需要我们手动补充上
"engines": {
"node": ">=0.12.0",
"homebridge": ">=0.2.0"
}
解决方法来自Google(链接)