设备模型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提供的一项基础能力,它提供了在外网断连的情况下,局域网内设备控制的特性。

当外网断连的情况下,本地通信模块会去搜寻当前局域网内的设备,如果被发现的设备是之前用户控制过的设备,那么此时可以通过本地通信链路去控制设备。在外网断连时,如向云端拉取用户账号下的设备列表会失败,此时可以使用以下接口获取当前可以本地通信控制的设备列表。由于本地发现设备是一个较长的过程,所以第一次调用此接口时有可能返回为空,此时需要允许用户刷新设备列表。

此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参数的字符串,请参见生成物的模型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);
                        }
                    });
    					
  • 订阅所有事件
    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提供以下几方面的能力如下。

  • 提供发现蓝牙设备/连接蓝牙设备的能力
  • 提供连云通道,可以供蓝牙设备数据上下云
  • 提供蓝牙设备控制与数据获取的能力
依赖 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。

  • 使用蓝牙接入注意事项

    使用蓝牙设备前,App必须有如下权限,缺一不可。

    • 蓝牙权限
    • 蓝牙管理权限

    同时在apilevel 21(含level 21)之上的Anroid系统,须额外具有如下权限,缺一不可。

    • 低精度位置权限
    • 高精度位置权限

    除了上述权限,在apilevel 21(含level 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);
        }
      });
  • 控制蓝牙设备

    蓝牙设备的控制以及信息获取跟WiFi设备的API一致,可以参考本文档前部分的内容。