返回 登录
0

使用homebridge-mqtt对接设备到HomeKit

阅读11992

本文作者:梁中琪,广州大树信息技术有限公司嵌入式开发工程师,擅长单片机和Python开发。
本文为CSDN约稿文章,版权所有,转载请微信联系jiaweidi1214
关注物联网领域,投稿或有报道需求请邮件联系jiawd@csdn.net

Homebridge简介

Homebridge 是一个轻量级 Node.js 服务器,用 NodeJS 模拟了一个HomeKit Accessory Server,可以在家庭网络上模拟iOS HomeKit API运行。

Homebridge 逆向了 HomeKit 协议,让普通的 Wi-Fi 设备也能接入 HomeKit ,从而通过 Siri 控制。

Homebridge 的作者 KhaosT 是个在美留学的中国人,曾在苹果的 HomeKit 团队实习过。据说当 KhaosT 逆向 HomeKit 之后写了篇博客,但由于涉及到商业机密被苹果法务要求删除文章,好在代码已经早就 fork 开了所以代码才得以流传到现在。试想要是当初代码没有开源,恐怕我们现在还享受不到这一成果呢。

根据 Homebridge 文档,Homebridge可以运行在Linux、Windows和macOS等系统,那么,这里的测试平台就以树莓派为例。

Homebridge-mqtt

Homebridge-mqtt是Homebridge一个动态插件。它以MVC模式设计。Homebridge-mqtt允许你通过mqtt API添加和控制配件,进而通过苹果的HomeKit应用控制这些设备。

安装
Homebridge的安装需要npm,树莓派下安装npm有点麻烦,这里就不详细描述。安装好npm后只需按顺序输入下面语句即可安装homebridge及其相关依赖包。

sudo npm install -g --unsafe-perm homebridge hap-nodejs node-gyp
cd /usr/local/lib/node_modules/homebridge/
sudo npm install --unsafe-perm bignum
cd /usr/local/lib/node_modules/hap-nodejs/node_modules/mdns
sudo node-gyp BUILDTYPE=Release rebuild

接下来可以安装homebridge-mqtt了。

npm install -g homebridge-mqtt

配置
在树莓派上,Homebridge 的配置主要是编辑「/home/pi/.homebridge」下的「config.json」文件。下面是homebridge-mqtt 配置示例。

{
"bridge": {
"name": "Homebridge",
"username": "12:34:56:78:90:AB",
"port": 38960,
"pin": "123-45-678"
},
    "platforms": [{
 "platform": "mqtt",
    "name": "mqtt",
    "url": "mqtt://127.0.0.1",
    "port": 61613,
    "topic_type": "multiple",
    "topic_prefix": "homebridge",
    "username": "admin",
    "password": "password",
    "cert": "/path/to/certificate.pem",
    "key": "path/to/key.pem",
    "ca": "/path/to/ca_certificate.pem"
}]
}

其中,与 homebridge 配置相关的是 bridge 字段。name 表示 homebridge 要在 HomeKit 显示的名称;username 一般是本地主机的 MAC 地址;port 是使用的端口;pin 则是 HomeKit 配对的时候,需要输入的 pin 码。homebridge-mqtt 配置字段的含义,则参考下表。

图片描述
表1 homebridge-mqtt 配置字段含义

如果需要添加其他platform,就在「platforms」数组字段里继续添加json即可。

启动
控制台启动 homebridge 很简单,直接输入「homebridge」即可。如果需要指定配置文件路径,可以使用「-U」参数。例如:「homebridge -U ~/.homebridge」

Homebridge-mqtt的接口

Homebridge-mqtt通过MQTT提供接口(mqtt API),这些接口表征为mqtt的主题。我们可以通过这些主题做一些操作,比如添加配件或获取配件信息等等,当消息发布后 Homebridge-mqtt 会通过response主题发布消息作为响应。其实这一点非常类似于HTTP的请求/响应的思想,只不过是以MQTT的方式实现,一点也不难理解。部分mqtt API参见下表:

图片描述
表2 Homebridge-mqtt部分mqtt API

主题中有「to」字符的,表示这个主题是给我们发布消息使用,带有「from」字符的,表示我们需要订阅使用。mqtt API的负荷(Payload)采用JSON格式。

众所周知,数据库常用的操作就是增删查改。那么对 Homebridge 这个「网关」也是一样的思路。首先我们需要给Homebridge添加设备,这样我们才可以查询设备的数据,或者发送一个请求改变设备的数值,最后如果不需要设备了可以移除该设备。
在 mqtt API 中,增加操作有「添加配件」和「添加服务」,删除操作有「移除配件」和「移除服务」。如果用户端需要查询设备状态,那么可以使用

「homebridge/to/get」主题发布消息。实际上当我们从锁屏界面打开 HomeKit ,Homebridge 网关都会发送一条携带了设备状态信息的 homebridge/to/get 主题消息。

支持的service

添加配件是需要一个明确的 service,service 和苹果的HomeKit有对应的关系。比如如果service 选择了 Lightbulb,HomeKit 里会也会显示一个灯泡??的图标。下表是 Homebridge-mqtt 支持的部分 service。

图片描述
表3 Homebridge-mqtt支持的部分service

应用实例

下面是一些Homebridge-mqtt的实例。

添加配件
如果要添加配件,可以发布下面的消息:

topic: homebridge/to/add
payload: {"name": "flex_lamp", "service_name": "light", "service": "Switch"}

之后相关主题会做出下面的响应:

topic: homebridge/from/response
payload: {"ack": true, "message": "accessory 'flex_lamp' service_name 'light' is added."}

在发布消息的字段中,配件是根据 name 字段的不同来区分的,相同 name 不能重复添加。service_name 字段是设置默认出现在 HomeKit 里设备名称。service 字段上节已经说明。

移除配件

topic: homebridge/to/remove
payload: {"name": "flex_lamp"}

查询配件

topic: homebridge/to/get
payload: {"name": "flex_lamp"}

如果需要查询所有配件,可以给name字段换为星号(*)。

topic: homebridge/to/get
payload: {"name": "*"}

Homebridge操作设备
如下图,Homebridge可以理解为转发网关,使用MQTT连接一个MQTT服务器(MQTT Broker),通过MQTT服务器对设备端进行操作。

图片描述
图1 设备对接Homebridge-mqtt架构

在设备端,我们需要订阅「homebridge/from/set」主题,表示数据从(from)Homebridge出发,到达(set)订阅该主题的设备。此时,Homebridge类似于C/S架构中的client,设备端为server。

topic: homebridge/from/set
payload: {"name": "flex_lamp", "service_name": "light", "characteristic": "On", "value": true}

其中 characteristic 可以理解为特性或属性, 其根据 service 的不同而不同。一般来说,具有开关功能的 service (比如Switch、Lightbulb和Fan)都会带有「On」的 characteristic ,「On」的 value 字段只能是布尔值。而像窗户(Window)和窗帘(WindowCovering)这类 service, 可以在一个数值范围内设置开启的大小,当然这需要设备在物理层次上的支持。

Homebridge获取设备数据
如果Homebridge需要获取设备数据,可以使用「homebridge/to/set」主题。更准确地说,是其他设备主动设置值到Homebridge。此时,设备端类似于client,Homebridge为server。

控灯设备把状态发送Homebridge。

topic: homebridge/to/set
payload: {"name": "flex_lamp", "service_name": "light","characteristic": "On", "value": true}

像温度/湿度/光照传感器这类 service ,其本身不能被操作,但可以把数据发送到 Homebridge,它们 characteristic 字段根据 service 类型的不同而不同,所携带的 value 一般都是整型。

测温设备把温度发送到 Homebridge。

topic: homebridge/to/set
payload: {"name": "room_temp", "service_name": "temperature", "characteristic": "CurrentTemperature", "value": 26}

图片描述
HomeKit组图

图1HomeKit界面,图2添加配件,图3输入pin,图4识别配件,图5配件状态,图6打开light,图7添加温度传感器,图8light配件详情。

总结

当然,笔者后来思考了一下 Homebridge-mqtt 是否可以实现设备联动和第三方应用端的对接。

所谓设备联动,在Homebridge-Assistant中也称为家庭自动化。比如,如果检测到房间有人并且温度超过30度,可以自动关闭窗户并打开空调。由于没有在Homebridge-mqtt看到相关接口,所以要在 Homebridge-mqtt 实现设备联动功能恐怕有点困难。当然其实我们可能并不需要 Homebridge-mqtt,只需要MQTT服务器就可以了。我们可以自定义一些MQTT主题(topic),然后某些设备达到某条件后可以发布消息,另外一些设备订阅这些主题即可实现联动。

同理,第三方应用端控制设备同样也可以不通过 Homebridge-mqtt 接口,最简单的IoT架构就是APP+MQTT+Device。需要思考的是设备状态变化后如何通知Homebridge,在应用端或者设备端调用 Homebridge-mqtt 接口估计都是可以选择的方案。

至少,Homebridge-mqtt 把「让设备可以通过MQTT协议和Homebridge对接,并可以通过HomeKit进行控制」这一重要的功能已经实现了。如果需要更多功能,还得自己动手扩展。

图片描述

评论