HOW-想清楚要做哪些事情
以一款智能插座为例,我讲的主题就是这个插座该怎么样来生产、怎么样来研发。第一步,我们先要把它分解。插座有很多结构件,比如五金件这些东西,所以我们要搭建一个团队,包括做工业设计、结构设计的人,硬件工程师、电子类工程师、软件的工程师,以及生活端的,甚至是运营和销售的。如下图所示。
我们从传统的一个设备到智能设备转变的过程中,这一个东西非常重要,即WiFi模块。这个地方决定了这个设备到底能不能跟我们的App进行交互以及交互的效率如何。
大家可以看一下我们大概要做的事情,包括元器件选型、原理图、结构、工业设计、PCBA、打手板、开模,这些东西完成的话代表着传统的部分完成了,这里不再赘述。比较重要的是智能设备要怎样实现通讯。现在ZigBee、WiFi、Z-Wave、BLE,这四种用得比较普遍,还有433、315等设备。谷歌也有一套协议,但是应用得稍微少一点。我今天主要是从WiFi设备方面来讲,看到底一个WiFi设备到底要怎么样来做。
WiFi联网的难题
WiFi设备面临一个很大的难题,比如说我做一个智能的水杯、一个智能的插座,这个水杯和插座是没有交互界面的。但是我们必须解决一个问题,即这个设备一定要联网,要连路由器。大家想到最直接的办法是手机连路由器,打开手机的设置,进入WiFi列表,然后再输入密码。但是智能硬件里面没有办法进行操作,这就是要面临的第一个难题了,所以很多人内心是非常忧伤的。
这里介绍几种给WiFi设备配置的方法。第一种是AP,AP是最传统的方式,在AP里面主要是让智能设备首先进入AP模式里面,这样能够共享一个热点出来。我们的手机直接连到这个设备里面,然后再把路由器的SSID推送给那个设备,那个设备可以在线连路由器。这里面AP有一个很麻烦的事情,就是它的交互特别复杂,特别是在iOS手机里面不允许手机的App直接调用WiFi的设置或是直接切换过去,我们可能要先退出后台,然后切换到苹果的那一套设置里面,设置好了之后又要切换回来,这样特别麻烦。所以在演进过程中就进入了WPS。
WPS解决了第一步的问题,可以在路由器里面有一个按键,智能设备里面也有一个按键,可以根据WPS的协议交换它的密钥。但是这里面有一个很大的问题,WPS需要进行专门的认证,而且现在支持的路由器非常少,所以用WPS技术来做的话可能会比较差一点。
再接下来又出了一个Smart Config,这一款应用非常多,因为它非常简单,直接在手机上面向路由器发送SSID和密钥,这个芯片再去抓路由器的包,抓到这个包之后再解密,解密出来之后就知道了路由器的SSID和密钥,然后就可以去连。在这个基础上微信也出了air kiss和另外的Smart link,也这个原理。
接下来又出现了光配置,屏幕按照一定的亮变把信息传输过去,但是这个应用比较少一点,问题也比较多。
再接下来是声波配置,AA付款和面对面收款里面就用到这个技术。
总体来说,AP和第三个稍微比较好一点,但是我们在实际产品应用里面也会发现,这一类技术面临很多问题,就是对路由器的一些芯片、兼容性都会有比较高得要求。我们以前出现很多这样的例子,测试的时候拿了几十款、上百种路由器测得没有问题,到了用户家里,那一款路由器我们没有测试过,结果发现不行,这是一方面的限制。为了解决这种限制,后面又改成了不抓路由器的包,就抓手机发出来的包。抓手机发出来的包之后又带来更大的问题,正常手机的包是OK的,没有那么多兼容性的问题。去年iOS包出来的之后,苹果的iPhone6会有一个问题,连上WiFi离开一段时间再回来WiFi就会丢失了,这时候不重启手机就永远连不上WiFi了。苹果为了解决这个问题又更新部件,然后对这个又没有用了,又抓不了包了,所以对传统应有还是有限制。还有一些跟技术没有关系的限制,比如说现在比较好一点的路由器是支持2.5G和4G的。现在我们使用的模块都是只有2.4G的,如果手机是双频、路由器是双频的默认是是5G。所以我们又回到最原始的AP模式来,因为我们不用跟用户解释那么多东西,也没有很多兼容性的问题。
软件架构的选择
这是一个软件架构要怎么样选择的问题,就是我们现在智能设备联网最基本的需求是什么。我们来看一下这个图,智能设备联网之后要实现跟手机APP的交互,一方面APP如果要去控制它,它必须能够接收到APP发过来的控制信号。另一方面,如果直接在上面按,按完了之后这里面的状态要能够反馈到APP里面来。所以,我们在做技术选型的时候,最基本要实现这两个需求。
控制命令的上传和下发的问题,这里面决定了到底我们怎么来架构的问题。这是我昨天提出的问题,就是为了解释刚刚提出的需求。比如说我在QQ上发布信息说插座开一下灯,然后它说已经开了。我问它是什么状态,然后它告诉我它已经关了。我们要对智能设备进行控制,这里面基本的需求一个是数据,我要把想要的数据控制命令发给它,控制了之后又发回给我,这个做的事情其实就是IM的事情。我们做服务器端的架构的时候,最初考虑的方案就是选择了IM的方案。
物联网跟互联网实际上看起来有很大的差异,真正我们在做的时候还是殊途同归,我们还是都选择了IM的方案。
看一下最简单的IM架构,这里面要保持长连接,接下来做一些业务处理,下面是存储,如果App要去控制Device的时候,发到业务层处理完了之后,这里面有一个推送的,可以找到Device到底连了哪一台机,然后再把数据推送过来。如果Device自己的状态发生变化,它的数据要推送给APP,基本上是这样的工作流。如果App是黑莓等设备的,我们可能要专门推送到APNS里面来。
通信协议的选择
接下来我们还需要一个好的通信协议,现在很多通信协议是XMPP,很多社交软件都个在用,因为它开源做得比较好。MQTT是专门用来做物联网的协议。另外,PROTOBUF是谷歌的,这三个比较的话,MQTT和PROTOBUF是最适合做物联网通信协议的,因为这两个协议对数据量利用率非常高,不会带来额外的开销的。
快速构建云服务
再回到上图,如果我们要做这样一个系统,为了要简单快速的出这样一个产品,要利用很多开源的组件,比如说负载均衡这里,传统的里面是比较难做的,我们用的比较多硬件负载均衡是F5或者是淘宝的LVS,我认为LVS对于目前做硬件的来说肯定是够的。再下面Connect Server现在也有很现成的开源技术,如果采用XMPP协议的话可能要用F5,像很多也完完全全做好了,如果在TTP这一层优化比较好,做到八十到一百万长连接也没有问题,而且会特别简单。像很多轨道函数都写的非常好,我们都不用关心怎么管理这些线程质量、怎么管理连接,只要在上面写我们的业务代码就行了。另外,我们这里面要做集群,我们有很多服务的时候直接在上面注册,后面调用的时候不用关心今天多了一台机器、明天少了一台机器以及这个机器的ID是什么。另外,服务要远程交易,我们要考虑IPC框架,像淘宝和Facebook的一些,都是开源领域利用的非常好的。
我们肯定还要用到很多缓存,缓存方面我们用的比较多的。如果我们对开源的框架用得比较好,简单的这个系统很快就可以完成了,不需要我们写很多东西,只需要在上面写业务代码就能够直接做好了。
这里面就是刚刚说到的,如果你用Netty,只要在这里面写业务代码,当你接收到数据的时候这里面应该怎么做,包括这里面出了异常的时候要怎么做。如果选用Netty还要考虑到一个情况,高并发的时候需要对数据包做拆包的事情。我们经常发现这里接收到的数据并不是一个完整的数据,比如说我们发了大概2K左右的数据,它给到你的可能只有很少。如果这里面不完整,把组包放进来就可以了。具体的拆包、组包也提供了编码性和解码性,最重要的是在这个函数里面写你的业务代码。
我们要在设备端也实现接入,还要考虑嵌入式的开发。嵌入式也有一个问题,我们的设备都是需要成本的,不像写服务代码一样,服务器资源非常多,给到你很好的服务器可以用。在嵌入式方面,我们必须用最低的成本、最少的资源做最多的事情。每一个产品研发出来,第一代选用的芯片可能比较好一点,第二代为了这个产品能够卖得更好,可能会做更改,对我们来说可用的资源更多。通常我们用单片机,我们比较常用FreeRTOS,它没有TCPP协议的。做嵌入式开发的时候我们还会遇到更多的问题,像LWIP之类的,写这个协议站的人可能并没有用到很多产品,所以里面还是残留了很多BUG。这里面举了两个非常明显而且一定会遇到的问题,一个是TIME_WAIT,还有一个是CLOSE_WAIT,如果对方没有按照正常流程关闭,假如说我们的APP直接刷了,可能就会产生这个CLOSE_WAIT,它一直在那里等,我们可能只开放十多个端口接入,如果一直在等待,可能它就认为这个请求还是正常的,就不会把它释放出来。等我们给它分配的端口满了之后,下一个请求就再也接不进来了。一般有三次握手,如果断开了标志着有四次握手,我们发现它没有按照正常的四次握手,导致断开的时候少发了一些命令,所以就一直在等待,等待的时候数据怎么发也发不出来了。
还有我们经常可能会遇到一些问题,比如说这里面可用的只有10几K、64K,我们要在上面写代码,如果写了多线程,又是单核的CPU,这里面用的时间长了会产生很多的内存碎片。当内存碎片产生了之后,多线程再申请内存做其他事情的时候,比如说有一个线程需要申请的资源比较大的时候会申请不到,就会一直在那里等,就会发现是怎么回事,这个地方本来十几毫秒就可以处理完的,可能等了一秒钟或者两秒钟甚至时间更长时间才能处理,这就是时间用了长了之后产生了内存碎片。我们回收内存也做不了,所以经常要做被动的事情,要软重启一下,所有的线程再重新跑起来。
事情是否已经结束
回到接下来的一个问题,我们按照刚才的思路,我们把样品做好了,模块也开发好了,APP也做好了,是不是所有事情都完成了呢?举个例子,某手机厂商说要做“东半球最好的手机”,这等于是他的情怀,为什么呢?做硬件和软件非常大的区别是,纯互联网的硬件把程序代码写好就可以使用了,但是硬件来说的话还会涉及到很多生产工艺,还要做一些认证。比如说像我们的插座,我们要经过3C认证等等,如果过不了这个东西就不能卖。像这个手机当时出了一个问题,它那个表面的玻璃像普通的安卓手机一样,下面开了几个孔,苹果只开了五个孔,它开了三个孔,在生产里面要求的工艺非常高,开三个孔的情况下可能真正的良品率只能达到30%、40%,大部分开孔的时候会导致这个玻璃碎了。像这种情况下,我们会把一个产品设计的非常好,认为这个东西非常漂亮、工艺非常好,但实际上也要考虑我们的生产能不能做。
我们现在做出来一个整体的架构,上面是一些产品,下面是模块这里面是为了解决家里面的很多设备,所以有一个ZigBee的网关,通过网关再来连接。
这是我们的一个系统构架,比较复杂一点,因为这里面整个系统涉及到的业务特别多,它的产品也特别多。这里面接入的时候,其实整体上来说也都差不多,一个是设备层的接入,还有一些业务层,里面做了一些报表、数据分析,还有一些OTA,可能还有一块没有画出来,就是我们在做商业智能的时候实际上是刚刚那位朋友问了一个问题,就是我们有没有尝试做一些更加智能的分析之类的,实际上我们在根据用户的需求在梳理一些模型,我们希望这些数据能够帮我们分析用户现在是在做什么。一个最简单的例子,当某一个开关,可能是它每天晚上一点钟都会亮一下,亮一两分钟又灭了,这可能意味着那个用户有一个生物钟,因为生物钟时间非常准,他每天都是这个时间点做这个动作,比如说上厕所之类的,这个时候非常需要把房间的灯打开,包括走廊的灯、洗手间的灯都要打开。我们把这个事件分析出来,到了这个时间点之后就不用摸黑按这个开关了,我们会把这个几个开关打开,这就是他的路线。如果要能够做的更细致化一点的化,我们还会发现,如果我们在睡觉的时候突然之间醒过来,然后灯亮了,实际上是非常刺眼、非常难受的事情,我们在打开灯的时候,是不是把灯的亮度只调出一点点,有一点微弱的光,不会刺眼,又有足够的亮度可以照明,让他走过去。这是我们做的更深层次的分析。