设备模型 SDK
更新时间:2019-03-13 17:18:55
概述
设备模型 SDK 提供了 App 端的设备模型(属性,事件,服务),用来开发设备界面,实现手机对设备的查看和控制。
依赖 SDK | 概述 |
---|---|
API 通道 SDK | API 通道 SDK,提供 IoT 业务协议封装的 https 请求能力,并通过整合安全组件来提升通道的安全性。 |
长连接通道 SDK | 长连接通道SDK,提供 IoT 业务协议封装的云端数据下行能力;为 app 提供订阅、发布消息的能力, 和支持请求响应模型。 |
初始化
此功能模块依赖 API 通道 SDK,以及长连接通道 SDK。使用前请先初始化这两个 SDK。
SDK 初始化调用如下代码:
TmpSdk.init(getBaseContext(), new TmpInitConfig(TmpInitConfig.ONLINE));
在初始化之后需要调用发现接口发现本地设备。在网络情况发生变化时同样需要调用该接口。网络情况发生变化包括切换连接的路由器,从 WiFi 切换到 4g 网络等。
TmpSdk.getDeviceManager().discoverDevices(null,5000,null);
使用说明
获取本地发现且支持本地控制的设备列表
本地通信功能是设备模型 SDK 提供的一项基础能力,它提供了在外网断连的情况下,局域网内设备控制的 feature。
当外网断连的情况下,本地通信模块会去搜寻当前局域网内的设备,如果被发现的设备是之前用户控制过的设备,那么此时可以通过本地通信链路去控制设备。
在外网断连时,如向云端拉取用户账号下的设备列表会失败,此时可以使用以下接口获取当前可以本地通信控制的设备列表。由于本地发现设备是一个较长的过程,所以第一次调用此接口时有可能返回为空,此时需要允许用户刷新设备列表。
此 API 在 sdk 版本 2.1.4 中新增
DeviceManager.getInstance().getLocalAuthedDeviceDataList();
返回值是一个 JSONArray 对象,对象内的数据格式具体请参见 根据设备获取绑定关系协议的 AccountDevDTO 结构
设备创建
设备创建
PanelDevice panelDevice = new PanelDevice(iotid);
iotid 可以通过云端接口获取。具体请参见 物的核心模型服务。
panelDevice.init(context, new IPanelCallback() {
@Override
public void onComplete(boolean b, Object o) {
}
});
context是应用的上下文,IPanelCallback 是初始化回调接口
设备控制
设备控制是基于物的模型对设备定义的属性、事件、服务进行操作。关于属性、事件、服务的描述,请参见 生成物的模型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);
}
});
获取设备属性
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);
}
});
通过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是设置属性协议中params参数的字符串,请参见物的模型服务
调用服务
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是调用服务中params参数的字符串,请参见物的模型服务
订阅所有事件
panelDevice.subAllEvent(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);
iotid 参数是设备iotid
topic 参数是回调的事件主题字符串
Object data 是触发事件的内容
清理缓存
账号退出时需要清理账号缓存的数据
DeviceManager.getInstance().clearAccessTokenCache();
混淆配置
-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.**{*;}
更多功能
获取物的模型
panelDevice.getTsl(new IPanelCallback() {
@Override
public void onComplete(boolean bSuc, Object data) {
ALog.d(TAG,"doTslTest data:" + data) ;
}
});
开发者也可以使用云端接口来获取原始的物的模型。
具体请参见 物的核心模型服务-获取物的模板 。
Android 设备端支持
设备模型 SDK 不仅用于移动端 App 开发,也能用于运行 Android 系统的设备开发。
通过本地通信服务端可以让一个 Android 设备成为能被 APP 端访问和控制的设备。如带 Android 系统的空调,通过本地通信服务端可以让空调设备接收到 APP 端的操作请求,空调设备调整自身设置后返回响应的结果到 APP ,由 APP 显示最新的运行情况,整个过程在本地网络进行,安全快捷。
创建服务端设备
protected int mDefaultProfile = 3;
protected int mDefaultWorkMode = 3;
protected int mDefaultBrightness = 30;
//设置设备属性的初始值
Map<String,ValueWrapper> propertyValues = new HashMap<>();
propertyValues.put("profile",new ValueWrapper.IntValueWrapper(mDefaultProfile));
propertyValues.put("Brightness",new ValueWrapper.IntValueWrapper(mDefaultBrightness));
propertyValues.put("WorkMode",new ValueWrapper.IntValueWrapper(mDefaultWorkMode));
final DefaultServerConfig config = new DefaultServerConfig();
//服务端颁发的设备三元组
config.mIotProductKey = mIotProductKey;
config.mIotDeviceName = mIotDeviceName;
config.mIotSecret = mIotDeviceSecret;
//设置设备的基础信息
DeviceBasicData basicData = new DeviceBasicData();
basicData.setProductKey(productKey);
basicData.setDeviceName(deviceName);
//deviceModel为设备在后台开发得到的tsl字符串
basicData.setDeviceModelJson(deviceModel);
basicData.setLocal(true);
basicData.setPort(5683);
config.setBasicData(basicData);
config.setPropertValues(propertyValues);
//创建设备并初始化
IDevice mIDevice = DeviceManager.getInstance().createDevice(config);
mIDevice.init(null, new IDevListener() {
@Override
public void onSuccess(Object o, OutputParams outputParams) {
}
@Override
public void onFail(Object o, ErrorInfo errorInfo) {
}
});
注册设备信息并处理请求
在设备初始化成功后注册发现和设备三要素,处理客户端的请求并返回响应
注册发现协议并处理
mIDevice.regRes("dev",false, new ITResRequestHandler() {
@Override
public void onProcess(String s, InputParams inputParams, ITResResponseCallback itResResponseCallback) {
ValueWrapper valueWrapper = new ValueWrapper();
valueWrapper.setValue(deviceModelMap); itResResponseCallback.onComplete(TmpConstant.METHOD_IDENTIFIER_DEV,null,new OutputParams("deviceModel",valueWrapper));
}
});
注册三要素并处理
mIDevice.regRes("set",true, new ITResRequestHandler() {
@Override
public void onProcess(String identifier, InputParams inputParams, ITResResponseCallback itResResponseCallback) {
boolean isSuc = true;
OutputParams outputParams = new OutputParams();
//根据参数处理请求
//...
if(isSuc){ itResResponseCallback.onComplete("set",null,outputParams);
}else{
itResResponseCallback.onComplete("set",new ErrorInfo(ErrorCode.ERROR_CODE,ErrorCode.PARAM_ERR_DESC),null);
}
}
});
蓝牙设备支持
蓝牙设备受连接特性的约束,往往无法直接跟飞燕云端平台连接,因而需要借助一个网关设备来实现蓝牙设备与飞燕云端平台的连接通道。而手机在这一过程中也可以充当网关的角色。
此部分API提供以下几方面的能力:
1、提供发现蓝牙设备/连接蓝牙设备的能力
2、提供连云通道,可以供蓝牙设备数据上下云
3、提供蓝牙设备控制与数据获取的能力
依赖 SDK | 概述 |
---|---|
蓝牙 Breeze SDK | 是按照规范实现的手机端蓝牙 SDK,方便合作厂商在手机端快速接入蓝牙功能。Breeze SDK 包含的主要功能有:设备发现连接,设备通信,加密传输,大数据传输等 |
移动端设备网关 SDK | 移动端设备网关 SDK,运行于 APP 上的子设备网关,对于无法直连网络的子设备,如蓝牙设备,提供子设备的管理功能,如子设备添加拓扑,删除拓扑,上线,下线以及数据上下行等 |
蓝牙API依赖导入
在设备模型 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。请参见:移动端设备网关 SDK
使用蓝牙接入注意事项
使用蓝牙设备前,APP必须有如下权限,缺一不可:
- 蓝牙权限
- 蓝牙管理权限
同时在apilevel 21(包含)之上的anroid系统,必须额外有如下权限,缺一不可:
- 低精度位置权限
- 高精度位置权限
除了上述权限,在apilevel 21(包含)之上的anroid系统上,系统必须开启位置服务,否则扫描将无法正常工作,如何开启位置服务,参见这里
为什么需求位置权限及开启位置服务,参见讨论及官方说明
具体参见官方文档
发现蓝牙设备
final BoneDisFilter boneDisFilter = params==null?null:com.alibaba.fastjson.JSONObject.parseObject(String.valueOf(params),BoneDisFilter.class);
DeviceManager.getInstance().discoverDevices(null, false, 5000, new IDiscoveryFilter() {
@Override
public boolean doFilter(DeviceBasicData basicData) {
if(boneDisFilter == null){
ALog.d(TAG,"boneDisFilter null return true");
return true;
}
return boneDisFilter.doFilter(basicData);
}
},listener);
添加绑定蓝牙设备
蓝牙设备的绑定流程分为两个步骤
1、蓝牙设备通过 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));
}
}
});
2 上线成功后,调用云端 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);
连接/断开本地的蓝牙设备
此SDK相关功能在初始化后成功后,本地链路已经建立成功,不需要上层主动调用链接和断开接口。在一段时间后,遇见设备断开链接后,可以通过本地连接接口再次建立链接。
1 建立本地链接
panelDevice.startLocalConnect(new IPanelCallback() {
@Override
public void onComplete(boolean bSuc, Object o) {
ALog.d(TAG,"startLocalConnect, onComplete,"+bSuc);
}
});
2 断开本地链接
panelDevice.stopLocalConnect(new IPanelCallback() {
@Override
public void onComplete(boolean bSuc, Object o) {
ALog.d(TAG,"stopLocalConnect, onComplete,"+bSuc);
}
});
控制蓝牙设备
蓝牙设备的控制以及信息获取跟 Wi-Fi 设备的 API 是一致的,可以参考本文档前述章节。