物模型SDK提供了App端的物模型(属性、事件、服务),用来开发设备界面,实现手机对设备的查看和控制。
依赖 SDK | 概述 |
API通道SDK | API通道SDK,提供IoT业务协议封装的HTTPS请求能力,并通过整合安全组件来提升通道的安全性。 |
长连接通道SDK | 长连接通道SDK,提供IoT业务协议封装的云端数据下行能力;为App 提供订阅、发布消息的能力,和支持请求响应模型。 |
初始化
使用方式
本地通信功能是物模型SDK提供的一项基础能力,它提供了在外网断开的情况下,局域网内设备控制的特性。
当外网络断开时,本地通信模块会搜寻当前局域网内的设备,如果发现的设备是App用户曾经控制过的设备,此时可以通过本地通信链路去控制设备。
在外网断开时,向云端拉取用户账号下的设备列表会失败,此时可以使用以下接口获取当前可以本地通信控制的设备列表。此API在SDK2.1.4版本中新增。
DeviceManager.getInstance().getLocalAuthedDeviceDataList();
返回值是一个JSON Array对象,对象内的数据格式具体请参见根据设备获取绑定关系协议的AccountDevDTO结构。
设备创建
PanelDevice panelDevice = new PanelDevice(iotid);
iotid可以通过云端接口获取。具体请参见物的模型服务。
panelDevice.init(context, new IPanelCallback() {
@Override
public void onComplete(boolean bSuc, Object o) {
}
});
//context是应用的上下文,IPanelCallback是初始化回调接口
// bSuc表示初始化结果,true为成功,false为失败
// o表示具体的数据,失败时是一个AError结构,成功时忽略
设备控制
设备控制是基于物的模型对设备定义的属性、事件、服务进行操作。关于属性、事件、服务的描述,请参见 生成物的模型TSL。
- 获取设备状态
panelDevice.getStatus(new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"getStatus(), request complete," + bSuc); JSONObject data = new JSONObject((String)o); } }); // bSuc表示是否获取成功,true为成功,false为失败 // o 表示具体的数据,失败时是一个AError结构,成功时是json字符串格式如下 /* { "code":200, "data":{ "status":1 "time":1232341455 } } 说明:status表示设备生命周期,目前有以下几个状态, 0:未激活;1:上线;3:离线;8:禁用;time表示当前状态的开始时间 */
- 获取设备属性
panelDevice.getProperties(new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"getProps(), request complete," + bSuc); JSONObject data = new JSONObject((String)o); } }); //bSuc表示是否获取成功,true为成功,false为失败 //o表示具体的数据,失败时是一个AError结构,成功时是json字符串格式如下 /* { "code":200, "data":{ "WorkMode": { "time": 1516347450295, "value": 0 } } } */
通过panelDevice的
getProperties
接口,获取到设备当前的所有属性值。 - 设置设备属性
panelDevice.setProperties(paramsStr, new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"setProps(), request complete,"+bSuc); JSONObject data = new JSONObject((String)o); } }); //paramsStr 格式参考如下: /* { "items":{ "LightSwitch":0 }, "iotId":"s66CDxxxxXH000102" } */ //bSuc表示是否获取成功,true为成功,false为失败 //o表示具体的数据,失败时是一个AError结构,成功时忽略
paramsStr是设置属性协议中params参数的字符串,请参见生成物的模型TSL。
- 调用服务
panelDevice.invokeService(paramsStr, new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"callService(), request complete,"+bSuc); JSONObject data = new JSONObject((String)o); } }); //paramsStr 格式参考如下 /* { "args":{ "Saturation":80, "LightDuration":50, "Hue":325, "Value":50 }, "identifier":"Rhythm", "iotId":"s66CDxxxxItXH000102" } */ //bSuc表示是否获取成功,true为成功,false为失败 //o表示具体的数据,失败时是一个AError结构,成功时忽略
- 订阅所有事件
App上用户主动解绑一台设备或者在设备端reset,云端会主动向App发送通知。App收到推送通知后,SDK内部会自动清除相关缓存数据,且发出解绑通知。具体的解绑通知格式请参见调用示例。
panelDevice.subAllEvent( new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object data) { ALog.d(TAG,"doTslTest data:" + data) ; } } ,new IPanelEventCallback() { @Override public void onNotify(String iotid,String topic, Object data) { ALog.d(TAG,"onNofity(),topic = "+topic); JSONObject jData = new JSONObject((String)data); } } ,null); //IPanelCallback订阅成功或者失败时回调 //IPanelCallback的onComplete接口回调其中的参数 //bSuc表示是否获取成功,true为成功,false为失败 //o 表示具体的数据。失败时是一个AError结构,不会有事件回调,成功时忽略 //IPanelEventCallback在事件触发时回调 //iotid参数是设备iotid //topic参数是回调的事件主题字符串 //Object data参数是触发事件的内容,类型为json字符串,格式参考如下 /* { "params": { "iotId":"0300MSKL03xxxx4Sv4Za4", "productKey":"X5xxxxH7", "deviceName":"5gJtxDxxxxpisjX", "items":{ "temperature":{ "time":1510292697471, "value":30 } } }, "method":"thing.properties" } */ //当operation为Unbind时,表示该设备已解绑,解绑通知的格式参考如下 //topic: /sys/${pk}/${dn}/app/down/_thing/event/notify /* { "identifier":"awss.BindNotify", "value":{ "iotId":"apVtLzgkxxxxV000102", "identityId":"5063op37bxxxxxe0bfa9d98037", "owned":1, "productKey":"a2xxxxxyi", "deviceName":"IoT_Dev_33", "operation":"Unbind" } } */
清理缓存
账号退出时需要清理账号缓存的数据。
DeviceManager.getInstance().clearAccessTokenCache();
获取物的模型
panelDevice.getTslByCache(new IPanelCallback() {
@Override
public void onComplete(boolean bSuc, Object data) {
ALog.d(TAG,"doTslTest data:" + data) ;
}
});
//bSuc表示是否获取成功,true为成功,false为失败
//data 为具体的返回数据,格式为json字符串,失败时为一个AError结构
开发者也可以使用云端接口来获取原始的物的模型。具体请参见物的模型服务。
混淆配置
在proguard-rules.pro文件中,加入以下代码,排除不需要被混淆的类和方法。
-keep class com.aliyun.alink.linksdk.tmp.**{*;}
-keep class com.aliyun.alink.linksdk.cmp.**{*;}
-keep class com.aliyun.alink.linksdk.alcs.**{*;}
-keep class com.aliyun.iot.ble.**{*;}
-keep class com.aliyun.iot.breeze.**{*;}
蓝牙设备支持
蓝牙设备受连接特性的约束,往往无法直接跟生活物联网云端平台连接,因而需要借助一个网关设备来实现蓝牙设备与云端平台的连接通道。手机在这一过程中可以充当网关角色。
此部分API提供以下几方面的能力如下。
- 提供发现蓝牙设备/连接蓝牙设备的能力
- 提供连云通道,可以供蓝牙设备数据上下云
- 提供蓝牙设备控制与数据获取的能力
依赖 SDK | 概述 |
蓝牙 Breeze SDK | 是按照规范实现的手机端蓝牙 SDK,方便合作厂商在手机端快速接入蓝牙功能。Breeze SDK包含的主要功能有:设备发现连接,设备通信,加密传输,大数据传输等。 |
移动端设备网关 SDK | 移动端设备网关SDK,运行于App上的子设备网关,对于无法直连网络的子设备,如蓝牙设备,提供子设备的管理功能,如子设备添加拓扑,删除拓扑,上线,下线以及数据上下行等。 |
- 蓝牙API依赖导入
在物模型SDK支持蓝牙设备时,需要导入如下的依赖。您可以在生活物联网控制台,SDK下载页面获取相关的版本(相关操作请参见下载并集成SDK)。
compile 'com.aliyun.alink.linksdk:lpbs-plugin-breeze:${version}' compile 'com.aliyun.alink.linksdk:breeze-biz:${version}' compile 'com.aliyun.alink.linksdk:breeze:${version}' compile 'com.aliyun.alink.linksdk:ble-library:${version}'
- 初始化移动端设备网关SDK
此功能模块依赖移动端设备网关SDK。使用前请先初始化该SDK。
- 使用蓝牙接入注意事项
使用蓝牙设备前,App必须有如下权限,缺一不可。
- 蓝牙权限
- 蓝牙管理权限
同时在apilevel 21(含level 21)之上的Anroid系统,须额外具有如下权限,缺一不可。
- 低精度位置权限
- 高精度位置权限
说明除了上述权限,在API level 21(含level 21)之上的Anroid系统上,系统必须开启位置服务,否则扫描将无法正常工作,如何开启位置服务,参见Android开发参考文档,需求位置权限及开启位置服务的原因,参见官方说明。
更多介绍,请参见官方文档。
- 发现蓝牙设备
//discoverDevices 接口为发现本地设备接口 //第一个参数是userdata,一般设置为null //第二个参数表示是否清理之前发现的设备。true表示清理;false表示不清理,一般使用false //第三个参数表示发现设备多久超时,单位为毫秒 //第四个参数是过滤接口,返回true表示该设备为业务层需要的设备;返回false表示将该设备排除 //第五个参数为返现回调接口,会将本地发现的设备通过该回调接口返回 DeviceManager.getInstance().discoverDevices(null, false, 5000, new IDiscoveryFilter() { @Override public boolean doFilter(DeviceBasicData basicData) { return true; } },listener);
- 添加绑定蓝牙设备
蓝牙设备的绑定流程分为两个步骤。
- 蓝牙设备通过App去云端上线,可以使用SDK提供的API完成。
DevService.subDeviceAuthenLogin(params, new DevService.ServiceListener() { @Override public void onComplete(boolean isSuccess,Object bundle) { ALog.e(TAG,"subDeviceAuthenLogin onComplete isSuccess:" + isSuccess + " bundle:" + bundle); String productKey = null; String deviceName = null; if(bundle != null && bundle instanceof Bundle){ Bundle resultBundle = (Bundle)bundle; productKey = resultBundle.getString(DevService.BUNDLE_KEY_PRODUCTKEY); deviceName = resultBundle.getString(DevService.BUNDLE_KEY_DEVICENAME); } if(boneCallback != null){ boneCallback.success(getRspObject(isSuccess,productKey,deviceName)); } } }); //params 参数是子设备信息,参考格式如下: /* { "iotId":"your iotid", "productKey":"your productkey", "deviceName":"your deviceName " } */ //ServiceListener 是回调接口, //isSuccess表示是否成功,true表示成功,false表示失败 //bundle是回调的扩展参数,包含设备的一些信息
- 上线成功后,调用云端API去做绑定账号。绑定成功后通知SDK已经绑定成功。
IoTCallback callback = new IotCallback(){ @Override void onFailure(IoTRequest var1, Exception var2){ } @Override void onResponse(IoTRequest var1, IoTResponse var2){ SubDevInfo subDevInfo = new SubDevInfo(deviceInfo.productKey,deviceInfo.deviceName); DevService.notifySubDeviceBinded(); } } Map<String, Object> params = new HashMap(); params.put("deviceName", deviceInfo.deviceName); params.put("productKey", deviceInfo.productKey); IoTRequest request = (new IoTRequestBuilder()).setApiVersion("1.0.3").setAuthType("iotAuth").setPath("/awss/time/window/user/bind").setParams(params).build(); IoTAPIClient ioTAPIClient = (new IoTAPIClientFactory()).getClient(); ioTAPIClient.send(request, callback); //api 网关请求,接口需要设备的productKey,deviceName //具体请参见API通道SDK
- 蓝牙设备通过App去云端上线,可以使用SDK提供的API完成。
- 连接/断开本地的蓝牙设备
此SDK相关功能在初始化后成功后,本地链路已经建立成功,不需要上层主动调用链接和断开接口。在一段时间后,遇见设备断开链接后,可以通过本地连接接口再次建立链接。
- 建立本地链接
panelDevice.startLocalConnect(new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"startLocalConnect, onComplete,"+bSuc); } }); // bSuc 表示初始化结果,true为成功,false为失败 // o 为扩展参数,成功时忽略,失败时是一个AError结构
- 断开本地链接
panelDevice.stopLocalConnect(new IPanelCallback() { @Override public void onComplete(boolean bSuc, Object o) { ALog.d(TAG,"stopLocalConnect, onComplete,"+bSuc); } }); // bSuc 表示初始化结果,true为成功,false为失败 // o 为扩展参数,成功时忽略,失败时是一个AError结构
- 建立本地链接
- 控制蓝牙设备
蓝牙设备的控制以及信息获取跟WiFi设备的API一致,参照本文档前部分的内容。