小米台灯在背后干了什么?

米家LED智能台灯

gtt 老婆年会奖励了一台小米LED智能台灯,样子非常具有科技感,灯光也很酷炫。我没有观点,只是觉得这个台灯和app不错,其他米家产品不做评价。

我感觉最牛逼的是“米家”智能控制终端,虽说在手机上控制家电似乎没有什么特别之处,和多了一个遥控器差不多,但是“米家”app控制台灯的响应速度给我留下了很深的印象,到底有多流畅?就像本地遥控器一样快,基本感觉不到什么延时,体验非常的棒。“米家”app的界面如下图所示,有兴趣的可以去官网查询。

WechatIMG2 WechatIMG1

目前常见的“智能家居”因为各种原因,手机控制命令基本都要通过“云端”来统一下发。那么实际会出现这样一种现象:家电明明就在你面前,从手机上发出的命令偏偏要绕到互联网,经过厂家的“云端”服务器处理之后,再回到家中的设备里,设备完成控制动作之后再将结果吐回“云端”,最终服务器告诉你的手机动作完成了。这面做的原因主要有两点:

  1. 只要上了云端才能保证“人在公司,遥控家里的家电”。
  2. 方便收集用户使用习惯,也就是用户行为分析,为“大数据”分析提供基础数据。

先撇开隐私啥的问题不说,关于通信协议,各厂商有各自的实现,比如米家基于 UDP 自己搞了一个协议;比如某东(其实是用 broadlink的技术)基于 QUIC 协议,虽然也是基于 UDP 协议,但是比较重。通信协议的好坏可是直接影响到用户体验的,如果通信做的渣,用户发现在手机上按下按钮需要等待几秒家电才有反应,基本就不要指望用户会再次使用所谓的”智能“功能了。不过,gtt觉得米家在这方面做的还是挺到位的。

作为一个非常无聊技术人员,gtt 在家里搭建了一个环境来研究米家的通信原理。思路比较简单,把 macbook 接上有线网卡,通过共享网络的方式把 macbook 做成无线热点,然后将手机和智能台灯都连上 macbook 的热点,接下来在 mac 上用 wireshark 抓包,就能看到智能台灯的所有报文了。

首先按照智能台灯的说明书将 wifi 参数设置到台灯里,让台灯成功脸上 macbook 的热点,拔下台灯插头(确保断电重启),然后开始抓包。

域名解析

dns resolve

台灯上电后,一旦成功连上 wifi,首先会解析一个域名:ot.io.mi.com,这个就是米家的云端了,之后设备和云端的所有交互全部通过这个域名。

mi.com

接着台灯就开始不间断的向云端汇报运行情况,一开始报文比较密集,会慢慢趋于稳定。所有的通信都是基于 UDP 协议的,并且报文是加密的,不知道加密算法是什么。

心跳

每隔大概10秒左右,台灯会往 ot.io.mi.com 发送一个报文,云端回复一个内容一样的报文(可以看到报文长度和内容一样),应该是类似心跳或者 ACK/SYN 机制,这样云端就很好判断“设备是否离线“了。另外,不断向云端发送心跳还可以保持 UDP 打洞的稳定性。不了解 “UDP 打洞”的同学可以参考:维基百科

heartbeat

发送统计信息

台灯间隔一段时间还会调用一个 HTTP 接口,貌似是 yeelight 的统计接口。虽然是 http 协议,但是 body 是加密的,看不出是啥东西。

POST http://cloud.yeelight.com/sapi/wifi_device_stats

yeelight-report

可以看出云端实现是 php 的 Laravel 框架,而且前端还架设了 Nginx 反向代理。

控制命令下发

在手机上使用“米家”app控制台灯,手机会连接小米的一个 https 服务(gtt 忘记这部分的抓包截图了)。抓包能看到云端直接向台灯发送了好多 UDP 的报文,台灯对每一个指令进行响应。截图中 Len=32 的都是心跳包,从高亮的那个包开始是云端下发的命令。从云端主动下发命令要求 UDP 打洞的畅通,如果 UDP 洞不在了,处在内网的台灯就会收不到云端下发的命令。

command from cloud

关灯后依然维持发心跳

即使关灯后,不管是按物理按键还是手机app上控制关灯。关灯后的台灯依然会保持向云端发送心跳。要不然怎么实现“在野外控制家里的一切”,所以开头我说要拔下插头重启台灯。

以上就是 gtt 对小米智能台灯的通信协议的分析。

, ,

发表评论

电子邮件地址不会被公开。 必填项已用*标注