添加设备
更新时间:2019-09-06 11:33:29
添加设备
概述
提供了把 WiFi 设备配置上家庭路由器以及局域网内已联网设备的发现能力,具体方案包括一键广播配网(P2P)、手机热点配网、智能路由器配网以及设备间相互配网等。
依赖SDK | 概述 |
---|---|
API 通道 | 提供云端 API 通道能力 |
账号 SDK | 提供云端 API 通道身份认证 |
初始化
参见平台下载包中的说明文档。
使用方式
添加设备目前有两种方式,一种是通过本地设备发现进行引导配网,另外一种通过点击品类列表或者扫描二维码进行引导配网。
其中品类或者扫描二维码都会能获取到设备的PK信息,扫码还有可能获取设备的DeviceName信息,本地发现可以发现更多的设备信息,具体可以参考下面的设备发现章节。
拿到设备信息后我们可以使用 Bone 配网插件辅助进行,用户只需将品类列表中的PK信息或者扫码得到的PK信息跳转到 Bone 配网插件即可自动完成配网流程,如不想使用 Bone 配网插件 想根据 Native 自行开发请参考下面的设备配网章节。(注意,蓝牙辅助配网目前只能 Native 实现插件面板暂不支持)
设备发现
提供局域网内发现已配网的设备,包括 WiFi 设备以及以太网设备,以及局域网内已上电的待配设备(前提是当前局域网内已经有一个已配好网的智能设备,且该设备具有发现待配网设备的能力)的能力。
关于设备发现相关 API,请参见:LocalDeviceMgr 。
启动设备发现
发现本地的已配网设备,或者零配、路由器发现的待配设备,或者符合adh{pk}{mac}格式的设备热点设备。发现的待配设备信息可以作为后续设备配网的入参信息。如果需要对已发现的已配网设备做过滤(如过滤已绑定的设备,不支持的设备等)。
// 开始发现设备
// enumSet 是需要使用的防发现方式 EnumSet<DiscoveryType>, 请根据需要选择发现方式,并添加对应的依赖;
// 第三个参数是获取零配或智能路由器发现的待配设备 请求时需要携带的参数
LocalDeviceMgr.getInstance().startDiscovery(context, enumSet, null, new IDeviceDiscoveryListener() {
@Override
public void onDeviceFound(DiscoveryType discoveryType, List<DeviceInfo> list) {
// 发现的设备
// LOCAL_ONLINE_DEVICE 当前和手机在同一局域网已配网在线的设备
// CLOUD_ENROLLEE_DEVICE 零配或智能路由器发现的待配设备
// BLE_ENROLLEE_DEVICE 发现的是蓝牙Wi-Fi双模设备(蓝牙模块广播的subType=2即为双模设备)
// SOFT_AP_DEVICE 发现的设备热点
// BEACON_DEVICE 一键配网发现的待配设备
// 注意:发现蓝牙设备需添加 breeze-biz SDK依赖
}
});
停止发现设备
停止发现本地已配和线上待配设备,调用该接口会清除已发现设备列表,确保与 startDiscovery 成对调用。
// 停止设备发现
LocalDeviceMgr.getInstance().stopDiscovery();
设备配网
关于设备配置添加相关 API 说明: AddDeviceBiz。
设置待配网设备信息
热点配网在正式开始添加设备之前需要先调用 HotspotHelper 相关接口,完成配网前置工作再进入该流程。热点配网前置流程调用,请参考热点配网前置流程。
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = "xx"; // 商家后台注册的 productKey,不可为空
deviceInfo.deviceName = "xxx";// 设备名, 可为空
deviceInfo.productId = "xxx";// 产品 ID, 蓝牙辅助配网必须
deviceInfo.id= "xxx";// 设备热点的id,在发现热点设备返回到APP的时候会带这个字段
// 设备热点配网 ForceAliLinkTypeSoftAP 蓝牙辅助配网 ForceAliLinkTypeBLE
// 二维码配网 ForceAliLinkTypeQR 手机热点配网 ForceAliLinkTypePhoneAP
// 一键配网 ForceAliLinkTypeBroadcast 零配 ForceAliLinkTypeZeroAP
deviceInfo.linkType = "ForceAliLinkTypeNone"; // 默认一键配网
//设置待添加设备的基本信息
AddDeviceBiz.getInstance().setDevice(DeviceInfo deviceinfo);
配网时,指定的配网方式 linkType,请参见 LinkType;
设备信息相关实体类,请参见 DeviceInfo。
开始设备配网
上述设置好待添加设备信息,进入配网。调用 startAddDevice 接口进入配网流程。
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = "xx"; // 商家后台注册的 productKey, 不可为空
deviceInfo.deviceName = "xxx";// 设备名, 可为空
// 开始添加设备
AddDeviceBiz.getInstance().startAddDevice(context, new IAddDeviceListener(){
@Override
public void onPreCheck(boolean b, DCErrorCode dcErrorCode) {
// 参数检测回调
}
@Override
public void onProvisionPrepare() {
// 提示用户输入账号密码 广播配网方式的时候会有这个回调
}
@Override
public void onProvisioning() {
// 配网中
}
@Override
public void onProvisionStatus(ProvisionStatus provisionStatus) {
// 配网状态
}
@Override
public void onProvisionedResult(boolean b, DeviceInfo deviceInfo, DCErrorCode dcErrorCode) {
// 配网结果
}
});
配网回调接口,请参见 IAddDeviceListener。
开始广播配网
在收到 onProvisionPrepare 回调后,引导用户输入 ssid 和 password ,并调用此方法传入 ssid、password、timeout 信息启动配网。 只有广播配网场景下,才会触发 onProvisionPrepare 回调。
String ssid = "ssid";
String ssid = "xxxxxxxx";
int timeout = 60;//单位秒
AddDeviceBiz.getInstance().toggleProvision(ssid, password, timeout);
停止配网
// 停止配网
AddDeviceBiz.getInstance().stopAddDevice(context);
设置配网模式
String linkType = "ForceAliLinkTypeBroadcast";
// 设置配网模式
AddDeviceBiz.getInstance().setAliProvisionMode(linkType);
热点配网前置流程
提供手机热点配网支持的相关 API。
关于热点配网相关 API,请参见:HotspotHelper。
创建热点
// 创建热点
HotspotHelper.getInstance().setupWifiAP(context,new HotspotHelper.ISetupWifiAPListener(){
@Override
public void onEnable() {
// 热点开启成功
}
@Override
public void onFail() {
// 热点开启失败
}
});
创建热点回调接口,请参见: ISetupWifiAPListener。
开始发现
开始发现连接到热点的设备,可能会多次回调。
// 开发发现设备
HotspotHelper.getInstance().discoveryDevices(new HotspotHelper.IPAPDiscoveryListener(){
@Override
public void onFound(LocalDevice localDevice) {
// 发现的设备
}
});
连接上热点的设备信息实体类,请参见: LocalDevice。
连接热点设备发现回调接口,请参见: IPAPDiscoveryListener。
停止发现
// 停止设备发现
HotspotHelper.getInstance().stopDiscovery();
设备切换 WiFi
// 发送账号密码到待配网设备
HotspotHelper.getInstance().switchAP(device, ssid, pwd, new HotspotHelper.ISwitchApResultListenr(){
public void onSucc(DeviceInfo info){}
public void onFail(String msg){}
};
发送AP账号密码给指定的已连接热点的设备回调接口,请参见: ISwitchApResultListenr。
恢复手机 WiFi 连接
收到设备端返回的切换 WiFi 的成功回调之后调用恢复 WiFi 的接口。
// 关闭热点 恢复 WiFi 连接
HotspotHelper.getInstance().recoverWiFiConnect(context);
恢复手机 WiFi 连接之后,直接调用 startAddDevice 接口进入设备配网监听,并在 onProvisionedResult 回调结果中接收是否配网成功的回调。
蓝牙设备支持
蓝牙设备受连接特性的约束,往往无法直接跟云端平台连接,因而需要借助一个网关设备来实现蓝牙设备与飞燕云端平台的连接通道。而手机在这一过程中也可以充当网关的角色。
此部分API提供以下几方面的能力:
1、提供发现蓝牙设备/连接蓝牙设备的能力
2、提供连云通道,可以供蓝牙设备数据上下云
3、提供蓝牙设备控制与数据获取的能力
使用蓝牙接入注意事项
使用蓝牙设备前,APP必须有如下权限,缺一不可:
1. 蓝牙权限
2. 蓝牙管理权限
同时在apilevel 21(包含)之上的anroid系统,必须额外有如下权限,缺一不可:
1. 低精度位置权限
2. 高精度位置权限
除了上述权限,在apilevel 21(包含)之上的anroid系统上,系统必须开启位置服务,否则扫描将无法正常工作,如何开启位置服务,参见这里https://developer.android.com/reference/android/provider/Settings.html#ACTION_LOCATION_SOURCE_SETTINGS
为什么需求位置权限及开启位置服务,参见讨论及https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id
具体参见https://developer.android.com/guide/topics/connectivity/bluetooth-le#permissions
蓝牙API依赖导入
在设备模型 SDK 支持蓝牙设备,需要导入如下的依赖:
implementation 'com.aliyun.alink.linksdk:lpbs-plugin-breeze:1.0.5'
implementation 'com.aliyun.alink.linksdk:breeze-biz:1.1.2'
implementation 'com.aliyun.alink.linksdk:breeze:1.2.5'
implementation 'com.aliyun.alink.linksdk:ble-library:1.2.3'
初始化
在初始化长连接通道后初始化App 网关
String clientId = MobileChannel.getInstance().getClientId();
if (TextUtils.isEmpty(clientId)) {
//请检查长连接通道是否初始化成功
return;
}
String mobileProductKey = clientId.split("&")[1];
String mobileDeviceName = clientId.split("&")[0];
}
GatewayConnectConfig config = new GatewayConnectConfig(productKey, deviceName, "");
GatewayChannel.getInstance().startConnect(this, config, new IGatewayConnectListener() {
@Override
public void onConnectStateChange(GatewayConnectState state) {
Log.d(TAG,"onConnectStateChange(), state = "+state.toString());
if (state == GatewayConnectState.CONNECTED) {
Log.d(TAG,"网关建联成功");
}
}
});
发现蓝牙设备
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);
混淆配置
-keep public class com.aliyun.alink.business.devicecenter.** {*;}
-keep public class com.aliyun.alink.linksdk.alcs.coap.**{*;}
更多功能
获取设备绑定 Token
设备绑定的时候除了需要 productKey、deviceName,还需要一个设备端的 token,该接口提供从设备端获取绑定 token 的功能。WiFi 设备或者以太网设备均可以使用该接口获取绑定需要的 Token。以太网设备需要先获取到设备的 productKey、deviceName,可以参考使用 startDiscovery 接口去获取。
// 获取设备绑定 token
LocalDeviceMgr.getInstance().getDeviceToken(productKey, deviceName, 60*1000, new IOnDeviceTokenGetListener() {
@Override
public void onSuccess(String token) {
// TODO bind
}
@Override
public void onFail(String reason) {
}
});
SDK 依赖
Maven仓库地址
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases/"
}
// 阿里云仓库地址,包括了IOT事业部开发的SDK
Gradle 依赖
compile ('com.aliyun.alink.linksdk:ilop-devicecenter:1.2.4'){
transitive = true
}