Normal view

There are new articles available, click to refresh the page.
Before yesterdayPersonal Blogs

自己动手打造智能物联网设备

10 September 2017 at 15:00

自从前段时间研究了智能家居设备之后,我便迷上了物联网和开源硬件。玩遍了市面上各种常见的物联网产品,总觉得各有不足,于是我突发奇想:干脆自己做一个!

对于我而言,现在市面上的物联网产品最大的问题在于太过封闭,不同厂商的产品都得用自家的 App 才能使用,而且大多数用户体验实在不敢恭维。虽然通过我前一篇博文介绍的方法将它们接入到 HomeAssistant 和 HomeKit 之后使用自由度会高得多,但依然无法满足我自己编写家居智能控制程序的要求。

当我问 Siri 客厅的室温是多少的时候,数据是这样传输的:米家温湿度传感器读取温度数据、通过 ZigBee 信号发送给米家智能网关、通过 Wi-Fi 发送到路由器,路由器再传给树莓派、HA 存储数据、Homebridge 读取和广播数据、手机上的 HomeKit 再通过 Wi-Fi 读取数据……可想而知,数据传输的环节越多,稳定性和数据时效性就越低。比如我想做一个根据电视画面的亮度来调整房间灯光亮度的设备,当电视在播放夜间画面(亮度较低)的时候调暗房间灯光来减轻屏幕反光的影响,反之则调亮灯光方便我吃东西。这时候就需要以百毫秒级的速率来读取光线传感器的数据,一般的商业产品很难满足这种需求。

此外,价格也是很重要的因素:一个硬件成本不超过十元的智能插座零售价高达两百多元;即使选用相对便宜的米家系列传感器和 Sonoff 开关,要实现我心目中真正的智能家居——家中所有电器全部智能化、每个角落都有人体感应器也将是一笔非常可观的开支。

初识 Arduino

于是我开始深入了解开源硬件方面的知识来打造完全合乎自己要求的物联网设备,这时候我发现了 Arduino 这个开源电子原型平台。它本质上是一个单片机,有丰富的针脚接口用于连接各类传感器、伺服器和继电器等等。在电脑上用 Arduino IDE 编写代码后,可以很方便地写入到微控制器上执行。更重要的是由于 Arduino 的软硬件都是完全开源的,让我能以很低的成本获取所需的软件和硬件。

Arduino 有很多种版本,加之以开源的 PCB 图为基础自行生产的第三方产品可谓数不胜数,我选择的是一个可以和我的第三代 Raspberry Pi(树莓派)结合使用的版本——因为 Arduino 本身只是个单片机,并不能像树莓派之类基于 ARM 架构的微型电脑一样连接网络和存储大量数据。虽然市面上 Arduino 也有能实现相关功能的硬件模块,但我依然认为搭配熟悉的树莓派更简单好用。

这个 Arduino 通过串口与树莓派通讯,同时封装了树莓派上的所有 GPIO 针脚,所以需要将它用 USB 线连接到树莓派,然后再将整个 Arduino 都插在它上面。

接入传感器

市面上有非常多的传感器可供选择,且售价大多不过二三十元。Arduino 支持接入模拟和数字两种信号的传感器,我第一个接入的温湿度传感器 DHT11 属于后者,所以要用杜邦线将它插到数字针脚上。

插好之后就可以开始写代码了。Arduino 主要用 C++ 来编程,这是一种我从未接触过的编程语言,还好我学过 Objective-C,所以还算是能读懂;配合万能的 Google、完善的官方文档和传感器厂商提供的实例代码,在开发过程中基本没有遇到什么困难。

虽然厂商提供了已经封装好的代码库,只需调用即可直接读取到传感器数据,不过我对从硬件电路到软件数据的传输和转换过程很感兴趣,于是一探究竟,才知道 Arduino 通过数字接口读取到的是 DHT11 传感器在一段时间内通过电压变化来传输的二进制数值:

按照官方数据表的说明,高电平输出 26 微秒左右表示 0,输出 70 微秒则表示 1,用逻辑分析器即可看到比较直观的效果,这里我偷个懒在网上找了一张已经标注好的图:

这里可以看到传感器总共输出了 40 位的数据,其中前 16 位是湿度,紧接着的 16 位是温度,最后 8 位则用于校验数据有效性,若为温湿度数值之和即为有效;温湿度的 16 位数据中只有前 8 位是有效数据,后 8 位是奇偶校验位,这里全部为 0,可直接忽略。

按照上述规则来解析,图片中的二进制湿度数据为 00011110,温度为 00011001,将它们转换成十进制即可得到最终结果:30% 相对湿度和 25 摄氏度。再计算一下 00011110 + 00011001 = 00110111,即最后 8 个奇偶校验位的数值,证明数据是有效的。

当然实际使用时并不需要自己计算这些,只要引入官方提供的代码库,简单调用一下即可获取传感器数值并通过串口输出,非常方便。

这里要吐槽一下 Arduino IDE 的代码编辑器,功能简陋到基本就是个带语法高亮的记事本,然而它的流畅性和视觉效果甚至还不如记事本……让我不得不在 Sublime Text 里写代码再复制过来编译。

接下来试试光线传感器,它传输的是模拟信号,所以要插在模拟接口的针脚上。软件方面就简单多了,调用 Arduino 内置的 analogRead() 方法即可获取亮度数据。

将数据传送到树莓派

现在已经可以用 Arduino 读取传感器的数据,接下来就要将数据传送到树莓派来做进一步处理。实际上之前所写的代码已经可以让 Arduino 把数据通过串口输出到树莓派上了,所以真正需要做的只是在树莓派上写个程序来读取串口输入的数据,我是用 Python 写的,只需六行代码。

测试成功后我又在 Arduino 上接入了六七种传感器,读取数据的方法都大同小异,这里就不再展开;不过随着数据量的增加,需要对数据进行封装才好解析。这里我选用了 ArduinoJson 库将数据转换为 JSON 格式输出,这样在树莓派上用 Python 读取就方便多了。

在树莓派上用 Python 读取到传感器数据之后,就可以自己写个程序通过我前一篇文章提到过的 HomeAssistant API 来自动控制家里的其他电器了。至此我的智能物联网终端已经初步完成,当然我还会继续研究如何实现更多新奇有趣的用法,包括如何进一步脱离网络传输,完全在本地直接控制电器等等,相信没有做不到,只有想不到。在学习 Arduino 传感器的过程中我还顺便了解到了很多关于电机、伺服器、继电器、ZigBee 通讯协议和无线充电的相关知识,让我很感兴趣,说不定哪天我会一时兴起,给它装上轮子和机械手臂,做成 AI 机器人管家之类的东西,哈哈。

HomeKit 智能家居深入体验

8 August 2017 at 16:55

作为一个从小就爱捣腾数码产品的人,我对智能家居自然有着浓厚的兴趣。最近家里重新装修,便换上了批智能家居设备,我也借此机会对这个新兴领域深入研究了一番。

我觉得智能家居最重要的一点,就是用起来要比传统的控制方式更方便。这听起来像是废话,可实现起来却并不太容易,毕竟绝大多数所谓“智能家居”配套的 App 都非常非常非常难用,比如下图这种画风……即便难得遇到些好用的,想控制不同厂商的设备还得打开不同的 App 也是挺傻的一件事。

还好 Apple 去年发布了 HomeKit 平台,通过这个平台可以将不同厂商的智能家居设备聚合在一起显示和控制,并且深度集成到了 iOS 系统里,在锁屏状态下都可以直接控制所有智能家居设备,完全不需要打开厂商提供的 App;甚至可以不碰手机,直接喊 Siri 帮你控制即可,非常方便(逼格也不知要高到哪里去了);配合 Apple TV 或 iPad 作为控制中枢还能实现人不在家时的远程遥控和自动化控制等等。

然而 HomeKit 虽然已经发布了一整年,硬件的支持情况却并不理想,在国内更是没有得到足够的重视,很多标榜智能家居的厂商甚至不知其为何物。无奈之余,我也本着极客精神,开始研究自行接入的方法。

梳理一下我家的电器设备,大致可分为以下三类:

  1. 原生支持 HomeKit 的设备,如 Philips Hue 系列灯具等;
  2. 完全不支持通过网络控制的传统电器,比如空调、新风系统和电动窗帘;
  3. 可以通过网络控制,却未提供原生 HomeKit 支持的设备,比如米家系列、Sonoff 开关和 Dyson 风扇。

下面我就分享一下我的研究(折腾)经历,看看我是如何把它们统统加进 HomeKit 里的。需要注意的一点是:本文仅为个人经验分享,并不是教程,所以一些细节问题我就不展开了。相信网上已经有了不少相关教程,若有需要可自行搜索,也可以在这里评论与我交流。

原生支持的设备

这里是指生产商官方提供 HomeKit 支持的设备,普通用户就能开箱即用。然而所支持的设备并不多,我手头只有 Philips Hue 系列灯具和 OPSO 的智能插座等。

添加 Hue 灯具的方法非常简单:把 Hue 网关用网线接到路由器上,在官方 app 里根据提示搜索并绑定网关,然后添加灯具即可,完成后扫描一下网关上的序列号,所有灯具都会自动同步到 HomeKit 里。

不得不说,Hue app 的界面设计和用户体验是我所用过的智能家居类应用里最好的。不过把灯都加进 HomeKit 之后,这个 app 也就没太大用处了。

接下来是 OPSO 的智能插座,这是 Apple Store 官网上的唯一一个支持 HomeKit 的国产设备,产品包装很有苹果风,做工也不错,只需在 iOS 自带的 Home app 里扫描设备上的序列号即可使用,非常方便。不足之处是有点不太稳定,使用几天后出现掉线的情况,需要重置设备后重新绑定才能用,希望可以尽快通过固件更新解决。

添加之后默认显示的是插座图标,不过可以手动将它修改成一个灯泡

这就是目前作为普通用户所能体验到的 HomeKit,但我并不会止步于此,下一步将会用些非常规的技术手段把那些并未提供原生支持的设备也加进来。

要实现上述功能,需要借助一个名为 Home Assistant 开源平台(下面简称 HA),它运行在基于 Linux 的系统上,可通过 Web App 和 API 来访问,接入不同的模块即可控制局域网内的各种智能家居设备。

搭建 HomeAssistant

首先需要一个基于 Linux 系统的设备来运行 HA,由于它需要 24 小时不间断运行,所以我选择了超低功耗的第三代 Raspberry Pi(树莓派)。它虽然才一个巴掌大,本质上却是个功能完善的、基于 ARM 架构的电脑,USB、HDMI 和网线等接口一应俱全。

考虑到这台树莓派主要用于运行 HA,我选用了 HA 官方提供的 hassbian 系统。从 HA 官网下载 hassbian 镜像,在电脑上用 Etcher 写入到空白 TF 卡中即可。

安装完成后,将 TF 卡、电源线和网线都插到树莓派上就可以开机了。首次启动时 hassbian 会自动安装和配置所需环境,等待一两分钟后,在局域网内的其他设备上访问 http://hassbian.local:8123 就可以进入 HA 的 Web App 主界面。

这里可以看到 HA 已经自动识别了 Philips Hue 网关和局域网内的两台 Apple TV。这里的 Hue 是可以一键配置的:点击 Configure 再按下 Hue 网关上的实体按钮即可将所有相关灯具都自动添加进来。虽然 Hue 灯具本身已经可以用 HomeKit 控制了,但在 HA 中可以实现更多有趣的玩法,比如自动循环变色等等。

接入传统遥控设备

下一步开始接入那些不能通过网络控制的传统电器,这里需要用到另一个硬件:可以联网的万能遥控器。经过一番比较,我选择了对 HA 支持较好的 BroadLink,它可以发射用于控制空调等电器的红外射频信号和窗帘电机的 FM 433Mhz 信号。

单从硬件角度来看 BroadLink 非常不错,但是它配套的 iOS app 实在是……太!差!了!还好它对 HA 有着良好的支持,所以用这个 app 把它连上 Wi-Fi 之后就可以果断删掉了。

按照官方文档中的说明将 BroadLink 的 IP 和 MAC 地址等信息填入 HA 的配置文件后,在服务列表里就可以看到它了。通过 HA 调用 learn_command 指令,BroadLink 将会进入学习状态。此时用空调遥控器对着它按下开机键,HA 首页便会显示遥控空调开机的指令代码。

接下来要做的就是将这个指令代码按照官方文档的格式复制到 HA 的配置文件里,并给它设置一个名称。用同样的方法配置关机键后,重启 HA 即可在首页看到空调的开关。在 Web App 上点击开关,HA 便会读取这个指令代码并通知 BroadLink 对着空调发送与普通遥控器相同的控制信号,达到通过网络控制电器的目的。

窗帘电机、风扇和空气净化器等其他有遥控器的电器设备也用同样的方法设置之后就都可以通过 HA 来控制了,下一步是将 HA 接入到 HomeKit 上。

连接 HA 与 HomeKit

这里需要用到一个叫做 Homebridge 的工具,它可以在树莓派上调用 iOS 的 HomeKit API 虚拟出一个网关来,然后再用它的 HA 插件将之前添加过的电器都同步到 Homebridge 即可实现操作。安装过程非常简单,参考这几篇官方教程即可:

Homebridge 的 Github 主页
https://github.com/nfarina/homebridge

在树莓派上安装
https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi

与 HA 建立连接
https://github.com/home-assistant/homebridge-homeassistant

安装完成之后就可以在 iOS 设备上的 Home app 里添加 Homebridge 了,这里与原生支持 HomeKit 的硬件相同的添加步骤完全相同,只不过设备名称和设备序列号都可以在配置文件里自定义,能把自己的名字写到“厂商名”处的感觉还是挺好玩的。

至此,HA 上的所有电器设备就都可以直接通过 HomeKit 来控制了。下一步接入能通过网络控制但未提供原生 HomeKit 支持的电器,比如小米家居(米家)系列。

接入无原生支持的设备

我家的绝大多数单联墙壁开关都是米家的 Aqara 系列,经由米家多功能网关控制。使用 homebridge-aqara 插件即可将小米网关添加到 Homebridge 上。

插件安装完成后,需要在配置文件里填入网关的协议密码和 MAC 地址,获取这些信息需要用到一个小窍门:首先打开米家 App(iOS / Android 版本均可)并绑定网关之后,点击网关界面右上角的 ··· 按钮进入“关于”界面,接着快速连续点击界面底部的空白区域,直到列表中出现“局域网通信协议”和“网关信息”的选项;接下来进入通信协议界面,打开上面的开关即可看到协议密码;MAC 地址则藏在“网关信息”界面里的那堆 JSON 格式的信息中。将这些信息一起复制到插件的配置文件里,保存并重启树莓派即可。由于之前已经将 Homebridge 添加到了 HomeKit 里,现在新加入的米家设备都会自动同步过来。

至此,我已经可以用 HomeKit 控制我家几乎所有的电器了,但这还仅仅是个开始。随着 iOS 11 的发布,HomeKit 平台也得到了进一步加强,同时相关协议也逐渐公开了,相信以后会变得更智能、更好用。借助 HA 和 HomeKit 这两个强大的平台,可以充分发挥想象力来实现一些很有意思的玩法。例如配合人体感应器实现走进房间时自动开灯;通过设置情景模式实现跟 Siri 说“我要去洗澡了”即可自动关窗帘和开浴室灯等等;此外,我还用 Sonoff 智能开关、淘宝二十元买的电磁水阀和五金店买的几截水管 DIY 了一个自动滴灌系统,出门在外时也可以远程操控它给家里的花花草草浇水。

题外话

除了 HomeKit 外,HA 还能配合 IFTTT 和 Workflow 等效率工具以及各种开源项目实现更高级的用法,以及通过 RESTful API 实现与各种编程语言的双向通讯,使自己编写家庭控制程序成为可能,即使你没有 iOS 设备也可以愉快地玩耍。

比如我就随手写了一个 Linux 的 HA 客户端,当我想在 macOS 上关闭卧室空调时只需输入如下命令即可。由于我经常开着 Terminal,所以用这个比打开浏览器再进入 HA 的管理页面控制要方便得多(同时还附带满分装逼效果)。

我还更进一步,用 Python 写了个小程序来实现更智能的自动化功能,它除了有根据实时天气自动调整室内的灯光之类的基础功能外,还可以和我日常生活中的其他方面连接起来,比如当我的网站或者 Vary 的服务器出现异常时,会将我房间的灯全部调成红色以作警示;当手机定位我和家人都不在家,但人体感应器又检测到有人活动的时候(有贼!)就把家里所有的灯都改成阴森昏暗的蓝绿色……由于本文是以 HomeKit 为题,这些高级玩法就不详细展开了,如果大家感兴趣我就找时间再单独写一篇文章谈谈吧。

❌
❌