物模型SDK

物模型SDK提供了App端的物模型(属性、事件、服务),用来开发设备界面,实现手机对设备的查看和控制。

依赖 SDK概述
API通道SDKAPI通道SDK,提供IoT业务协议封装的HTTPS请求能力,并通过整合安全组件来提升通道的安全性。
长连接通道SDK长连接通道SDK,提供IoT业务协议封装的云端数据下行能力;为App 提供订阅、发布消息的能力,和支持请求响应模型。

初始化

初始化前需确保已集成安全图片,初始化的操作请参见SDK初始化

使用方式

本地通信功能是物模型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
                      }
                }
            }
         */

    通过panelDevicegetProperties接口,获取到设备当前的所有属性值。

  • 设置设备属性
      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);
  • 添加绑定蓝牙设备

    蓝牙设备的绑定流程分为两个步骤。

    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));
                      }
                  }
              });
      
      
      //params 参数是子设备信息,参考格式如下:
      /*
      {
          "iotId":"your iotid",
          "productKey":"your productkey",
          "deviceName":"your deviceName "
      }
      */
      
      //ServiceListener 是回调接口,
      //isSuccess表示是否成功,true表示成功,false表示失败
      //bundle是回调的扩展参数,包含设备的一些信息
      
                                  
    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);
      
      
      //api 网关请求,接口需要设备的productKey,deviceName
      //具体请参见API通道SDK
  • 连接/断开本地的蓝牙设备

    此SDK相关功能在初始化后成功后,本地链路已经建立成功,不需要上层主动调用链接和断开接口。在一段时间后,遇见设备断开链接后,可以通过本地连接接口再次建立链接。

    1. 建立本地链接
      panelDevice.startLocalConnect(new IPanelCallback() {
        @Override
        public void onComplete(boolean bSuc, Object o) {
        ALog.d(TAG,"startLocalConnect, onComplete,"+bSuc);
        }
      });
      // bSuc 表示初始化结果,true为成功,false为失败
      // o 为扩展参数,成功时忽略,失败时是一个AError结构
    2. 断开本地链接
      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一致,参照本文档前部分的内容。