[智能家居](/smart-home-air-quality.html)最容易入手的一环就是智能灯光。从飞利浦的hue，到wemo的智能开关，到小米的智能灯泡，每家的技术都不一样，但基本都能实现遥控，定时开关等基本功能。结合Alexa/Siri还能实现语音控制。到了这一步，家庭灯光就已经比较智能了。这篇文章主要介绍的是，如何在这个基础上更进一步，加入人体感应功能。

一些品牌的灯光已经有了人体感应的功能，比如Hue有动作感应传感器，可以和Hue灯泡连起来。小米也有人体感应传感器。但它们的不足是，仅仅起到了自动开关灯的作用，和常见的声控灯没有太大区别。比如上厕所的时候还要一边拉屎一边鼓掌/挥舞自己的双手让灯不要超时，想想就酸爽。。同时这些传感器还并不能实现对灯光更精细的控制。比如起夜冲进厕所，啪，灯一下全打到最亮，我的氪金狗眼都要被亮瞎了。。所以，这篇文章主要介绍一下我对智能灯光应该如何做的人性化的一些思考和实现。

在定下具体的目标之前，我们先要了解一下我们手头有什么工具。最核心的当然就是红外传感器啦。长得像下图左这样，驱动电压5V。它里面有一个红外感应器（下图右）。如果有人走过的话，它会输出一个高电平，否则输出低电平。灵敏度和超时长度可调。它的一个致命缺陷是，如果你就在那一直坐着不动的话，它感应不到红外变化，就会觉得没有人了，输出低电平。换言之，这个传感器检测的是人动不动而不是人在不在。价格方面，5块人民币就可以买到。相比之下，同样原理的飞利浦Hue动作感应器需要300人民币左右（当然还包括配套电路，研发等等成本和品牌溢价）。

![PIR sensor](https://yage.ai/images/smart-home-lighting-pir.png)

的确有其他更高级的传感器和算法可以实现检测人在不在而不是动不动，比如摄像头可以轻松地实现这一点，或者在门口拉个红外/激光围栏也可以。但综合考虑成本和实现难度以后，我觉得这个红外传感器还是最合适的。只是因此我们也确定了一个我们不会去实现的功能，就是自动关灯。因为除非引入更多的传感器和更精细的算法，否则自动关灯很难做到人满意的程度。同时它带来的好处非常有限——现在的LED灯泡可以做到7W功率达到70W白炽灯的亮度。就算有自动关灯每天少开2个小时，也不过是0.014度电，按5毛钱一度电算，一年才能省2块多钱。考虑到投资和收益，我们并不需要自动关灯功能。
至于我们想要的功能主要是三点：

* 人经过自动开灯。比如晚上睡前想去厨房倒杯水，我可不想摸黑走路，或者大动干戈叫Alexa开灯。又比如起夜，在厕所摸开关摸半天也很不爽。
* 要能判断什么时候自动开灯，什么时候不要开。比如装在卧室的自动灯，老婆睡觉了我一进卧室灯打开了引发家庭暴力，我睡了翻个身又把灯打开了（这个可以通过改动传感器的位置实现）。
* 要能判断什么时候用什么亮度。比如我们的洗手间没有窗户，所以平时希望只要一有人进去就满亮度打开。但如果夜里进去的话希望开的比较暗，以免亮瞎狗眼。此外对于起夜的情况希望有个自动关灯功能，因为这个只靠定时也可以做得很好，而且这样就彻底不用碰开关了。

关于用什么机制来实现（机理设计），第一点非常简单，弄个微控制器，传感器高电平就联系Hue Bridge开灯就好（我们家用的是Hue）。二三点的关键是在于知道什么时候处于睡眠状态，什么时候解除睡眠状态。在前面的[智能家居文章](/zi-ji-dong-shou-gai-zao-zhi-neng-jia-ju-sheng-huo.html)里介绍过，我们的Alexa有个特殊的IFTTT trigger叫做good night。每晚睡觉前我们都会跟Alexa道晚安，这时候Alexa会自动关灯，关窗帘，启动摄像监控，激活警报器等等。只要在这里跟告诉自动灯控制器，激活睡眠模式就可以了。这时开始，所有房间的自动开灯功能就都被禁用了。除了洗手间仍然有自动开灯，但灯光亮度非常弱。至于什么时候解除睡眠模式，我们用的是IFTTT，每天日出的时候把洗手间设置成全亮度，日落的时候把其他房间的自动开灯功能打开。这样一方面比较智能，只在日光不足的时候自动开灯；一方面也比自己实现一个类似功能简单可靠。

下面具体介绍实现的技术细节。整个技术框架如下图所示。

![System framework](https://yage.ai/images/smart-home-lighting-framework.png)

具体的实现可以根据技术框图很容易给出来。几个要点是：

* ESP-8266不仅是一个Wifi芯片，而且是一个独立的微控制器（MCU），可以直接用Arduino IDE编程。而且它的能力比Arduino强很多。
* ESP-8266唯一的坑是它整个芯片都是3.3V的。但这个红外传感器只能用5V驱动，用3.3V的话会不断重启。有个很hacky的解决方法是，如果你用的是NodeMCU开发板的话，它是用5V电压驱动的，这个电压可以用USB输入，也可以用VIn输入。所以如果用USB输入的话，VIn其实是输出5V电压的。可以用这个来驱动红外传感器。但一个坑是，在芯片启动的那一刻，VIn不能连在传感器上，否则它会认为驱动电压不足。要等芯片启动以后再把传感器接上去。
* Hue Bridge的API非常简单。基本上是个RESTful API。网上有很多教程。可以用ESP-8266直接驱动，也可以在电脑端连。我选择了在电脑端连，是因为微控制器要重新编程调试比电脑上编程还是要麻烦不少（虽然ESP-8266可以无线更新）。如果不走API用IFTTT控制的话，延时可能会到10秒左右，实在不靠谱。所以我选择了在本地直接发送API请求的方式。
* 树莓派上的软件，我用的是tornado写了个web service。通过nginx反向代理，经过路由器把暴露在广域网上。然后IFTTT有个Maker channel可以通过这个接口来控制睡眠模式。

最终的成品如图所示。左上角的是红外传感器，旁边蓝色的是温湿度传感器。右下角的是ESP-8266开发板。注意Mini USB口和芯片的相对尺寸。所有电路传感器加起来还没有用来供电的充电器大。

![Final result](https://yage.ai/images/smart-home-lighting-result.jpg)

总结一下，这篇文章首先定了一个模糊的需求方向（自动开灯），然后调研市场上已有的解决方案，分析优势和不足，确定具体的目标和非目标。接下来敲定机理设计，一步步细化，到最终实现。一遍过程做下来，还是可以学到不少东西的。
[更新] 换了一个带5V输出的开发板，现在重启要手工干预的问题也解决了。同时用乐高搭了个丑萌丑萌的小盒子。。

![Final result with lego box](https://yage.ai/images/smart-home-lighting-lego.jpg)
