李峰 陈维 金海峰
(中移(杭州)信息技术有限公司 浙江省杭州市 311000)
在中国,智慧家庭家居市场不断增长,用户越来越关注自身的身体健康指标,蓝牙类的健康设备不断的进入到家庭中。智能音箱作为智慧家庭中枢,能够扫描并连接到蓝牙类的健康设备,并通过蓝牙实时传输和分析用户的健康数据,提醒用户关注身体异常。小荷音箱是中国移动为了满足智慧家庭需求,推出的智能音箱。健康业务是小荷音箱上的重点业务。
在实际使用场景中,用户在测量身体健康指标时才会打开相关的健康设备,测量结束就会关闭健康设备,有使用频次相对较高,单次使用时间较短的特点。鉴于用户这种使用健康设备的方式,设备的蓝牙在线时间短,即只在测量身体健康指标时时在线,测量身体健康指标结束就下线,整个过程只有几秒时间。小荷音箱在移动时,无法充电,而电池电量有限,又必须实时扫描并快速连接上蓝牙设备健康,获取到最新的健康数据,对音箱的应用提出了较高的能耗要求。本文分析了传统的蓝牙实时扫描并连接的方法,针对蓝牙在线时间短的特点和小荷音箱在移动应用中低功耗的需求,提出了一种在小荷音箱上较节能的音箱连接蓝牙设备的方案。
下文使用音箱连接方案代替本文描述的安卓系统蓝牙连接功耗优化方案。
低功耗蓝牙在使用中,会在就绪状态(StandbyState),扫描状态(Scanning State),广播状态(AdvertisingState),初始化状态(InitiatingState),连接状态(ConnectionState)这五种状态转换,如图1所示。
图1:蓝牙状态转换图
健康类蓝牙设备作为被连接端(Slave)上电后链路层(Linklayer)从就绪状态进入广播状态,发送广播数据包,持续advInterval时间,在停顿advDelay时间后继续发送广播数据包,并循环此过程。广播数据包含ADV_IND数据包(对应Connectable Undirected Event),ADV_DIRECTED_IND数据包(对应Connectable Directed Event),ADV_NONCONN_IND数据包(对应Non-connectable Undirected Event),ADV_SCAN_IND数据包(Scannable Undirected Event)四种主要类型。同时如果在广播状态中收到SCAN_REQ广播数据包,则需要回复SCAN_RSP 数据包。
安卓端的蓝牙作为连接端(Master),链路层(Linklayer)从就绪状态进入扫描状态, 在蓝牙广播信道上监听广播事件,持续scanWindow时间,然后停止监听,持续scanInterval时间后,接着切换到下一个广播信道,循环此过程。在接收到不重复的ADV_DIRECTED_IND数据包时,如果MAC地址包含本机地址,则需要通知Host收到广播数据。在收到其他不重复的广播事件时,都需要通知Host收到广播事件。在接收到ADV_IND或者ADV_SCAN_IND事件对应的数据包时,必须至少回复一个SCAN_REQ数据包。
安卓端的蓝牙作为连接端通过主机控制接口(HostController Interface)调用连接接口后链路层进入初始化状态,在蓝牙广播信道上监听广播事件,持续scanWindow时间,然后停止监听,持续scanInterval时间后,接着切换到下一个广播信道继续监听,循环此过程。在接收到ADV_DIRECTED_IND数据包时,如果包含本机MAC则需要发送CONNECT_REQ数据包。在接收到ADV_IND对应的数据包时,则需要发送CONNECT_REQ数据包。在此状态忽略其他类型广播数据包。安卓端的蓝牙链路层在发送CONNECT_REQ数据包后,蓝牙进入连接状态。当处于广播状态中的健康类蓝牙设备接收到CONNECT_REQ数据包,进入连接状态。
安卓端的蓝牙作为连接端和健康类蓝牙设备作为被连接端进入连接状态后就可以进行通行。
传统的蓝牙实时扫描连接方案,为了保证扫描连接的实时性和各种蓝牙设备的兼容性,会让作为连接端的安卓设备蓝牙链路层一直处于扫描状态,重复不间断的接收和发送各种广播事件,并有策略的通知上层应用扫描到的广播设备以及广播数据。上层应用接收到扫描数据时,通过广播数据判断当前扫描到的设备是否是本机需要连接的设备。如果是本机需要连接的蓝牙设备,则安卓端立刻发起连接请求。连接成功后,健康类蓝牙设备上传健康数据,安卓端在获取到数据后分析并完成实时监测和健康提醒的功能。该方案使用广播数据包中的数据判断设备是否匹配,兼容性较强。但是由于扫描状态需要处理较多的数据,发送广播数据需要较大的功率,因此电池电量消耗较大。
小荷安卓音箱端作为连接端在连接和使用蓝牙类健康设备之前,需要先进行绑定流程,将该健康类的蓝牙设备和音箱端的进行绑定,绑定后将该设备的MAC地址上报健康业务的云端保存,并约定蓝牙类的健康设备使用公开的设备MAC地址。用户在打开音箱后,音箱会获取到云端保存的已绑定设备的MAC地址列表,通过BluetoothAdapter.getRemoteDevice(String address)创建被连接的蓝牙设备对象,通过BluetoothDevice.connectGatt(Context context,bo oleanautoConnect,BluetoothGattCallbakccallback)使小荷音箱的蓝牙链路层进入连接状态,进行连接的过程,同时设置连接超时时间。如果在超时时间点到达时未成功连接上被连接的蓝牙设备,则认为该健康设备并未被使用,蓝牙是离线状态,在小荷音箱端重新通过连接接口尝试去连接该蓝牙设备,循环此步骤直到蓝牙设备连接成功或者程序退出。如果被连接的蓝牙设备在超时时间点到达前成功连接上,小荷音箱和已连接的蓝牙设备通信,请求被连接的蓝牙设备上传健康数据。小荷音箱在收到健康数据后,处理分析显示用户此次的健康数据,同时提示异常的健康指标。
传统的蓝牙实时扫描连接方案在健康类蓝牙设备未在线时,一直处于扫描状态,会接收并处理所有类型的广播包,并有策略的回复相应的广播包并回调到Host层,通知上层应用扫描结果。同时由于家居环境中有较多的其他类型的蓝牙设备在线,如手机,蓝牙耳机等非健康类的蓝牙设备,会不断发送广播数据,需要处于扫描状态的连接端设备处理并回复。而健康类蓝牙设备长时间处于离线状态,只有很短时间是在处在广播状态,发送广播数据,因此会浪费大量的能量在处理无意义的广播数据上。
音箱连接方案在音箱启动时从云端获取到设备的MAC,通过MAC创建蓝牙设备对象,进入设备连接流程,使音箱端的蓝牙跳过扫描状态进入初始化状态。图2是蓝牙扫描连接过程,蓝色箭头是扫描过程中的数据交互,红色箭头是初始化过程的数据交互。音箱连接方案只有红色箭头表示的过程,传统的蓝牙实时扫描连接方案为蓝色箭头表示的过程加上红色箭头表示的过程。
图2:蓝牙扫描连接
音箱连接方案有二大优势:
(1)过滤非目标设备的广播数据。音箱连接方案会过滤掉非音箱需要连接设备的蓝牙广播数据,无需将扫描到的设备信息和广播数据通过主机控制接口通知上层应用,减少了大量的广播数据处理逻辑和上层应用的交互次数。
(2)减少处理目标设备的广播数据包类型和逻辑。音箱连接方案处理2种广播数据包,即处理ADV_IND,ADV_DIRECTED_IND,比扫描状态少处理2种类型。由于无需处理ADV_SCAN_IND数据包,音箱无需再发送CONNECT_REQ数据包。同时收到ADV_IND数据时,无需发送SCAN_REQ广播数据包,代替为发送CONNECT_REQ数据包接入连接流程。
通过上述的优化处理,音箱连接方案能大量减少蓝牙连接中的处理逻辑,从而有效的降低的电池电量消耗。
为了直观对比两种方案的电池电量消耗情况,本实验使用单位时间内小荷音箱消耗的能量来衡量F(t) = Bluetooth_Battery_drain / t。Bluetooth_Battery_drain是本实验运行期间音箱蓝牙消耗的总毫安时,单位mAh,由于使用相同的小荷音箱,蓝牙的工作电压在两种方案中是基本相同的,Bluetooth_Battery_drain可以理解为实验运行期间音箱蓝牙每小时消耗的总能量。t是本实验的整体运行时间,单位秒。实验的数据利用安卓系统自带的batterystats工具获取,分别对两种方案获取三次的数据。
本实验中的音箱使用中国移动和家小荷带屏音箱,型号LDY-A1,健康类蓝牙设备使用鱼跃臂式电子血压计,型号YE650A。实验环境中有其他10个左右蓝牙设备在线,包含蓝牙手机,蓝牙耳机,蓝牙手表等多种蓝牙设备。
实验步骤如下:
(1)通过电脑adb工具连接音箱,运行adb shell dumpsysbatterystats-reset 指令,重置音箱端的电量统计数据并重新开始记录。
(2)启动传统蓝牙实时扫描连接方案的Demo程序,持续运行一段时间,不断的扫描周边的蓝牙设备。
(3)打开蓝牙血压计,血压计的蓝牙上线,用户使用血压计测量血压后关闭血压计,蓝牙离线。
(4)退出Demo程序,通过电脑adb工具,运行adb shell dumpsysbatterystats> batterystats.txt 指令,获取音箱端的电量统计数据,统计并分析得到单次传统蓝牙实时扫描连接方案的电量消耗数据。
(5)运行adb shell dumpsysbatterystats -reset 指令,重置音箱端的电量统计数据并重新开始记录
(6)启动音箱连接方案的Demo程序,持续运行一段时间,不断的连接蓝牙血压计。
(7)打开蓝牙血压计,血压计的蓝牙上线,用户使用血压计测量血压后关闭血压计,蓝牙离线。
(8)退出Demo程序,通过电脑adb工具,运行adb shell dumpsysbatterystats> batterystats.txt 指令,获取音箱端的电量统计数据,统计并分析得到单次音箱连接方案的电量消耗数据。
(9)重复步骤(1)-(8)二次,获取三组对比数据。
从表1实验数据可以得出,传统的蓝牙实时扫描连接方案平均的电池消耗较大,波动比较明显。而音箱连接方案平均电池消耗更小,单次的数据更优,波动较小,平均优化22.1%的电池消耗。实验结果数据证明了音箱连接方案在蓝牙设备实时连接方案中的可行性和优越性。
表1:实验数据
本文简单的介绍了蓝牙扫描连接的各个阶段,以及各个阶段的蓝牙执行的相关逻辑,阐述了传统的蓝牙实时扫描连接方案,即一直扫描,扫描后就连接的方法,并分析了该方案的优缺点。本文结合小荷音箱使用健康类蓝牙设备的应用场景下,针对音箱移动时电池电量有限的特性,利用蓝牙连接的特性,提出了一种更加省电节能的音箱连接方案。该方案利用蓝牙设备可以连接进入初始化状态,更有针对性的处理广播数据,优化整体流程从而有效的降低了蓝牙的电池电量消耗。最后通过理论分析和实验测试数据证明了该音箱方案在音箱侧的可行性,以及相比传统实时连接方案的优越性。