设备可以使用物模型功能,实现属性上报(如上报设备状态)、事件上报(上报设备异常或错误)和服务调用(通过云端调用设备提供的服务)。

设备属性

getDeviceThing() 返回的 IThing 接口介绍参见 IThing ApiReference

  • 设备属性上报

    // 设备上报
    Map<String, ValueWrapper> reportData  = new HashMap<>();
    // identifier 是云端定义的属性的唯一标识,valueWrapper是属性的值
    // reportData.put(identifier, valueWrapper);  // 参考示例,更多使用可参考demo 
    LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {
        public void onSuccess(String s, Object o) {
            // 属性上报成功
        }
        public void onError(String s, AError aError) {
            // 属性上报失败    
        }
    });
                    
  • 设备属性获取

    // 根据 identifier 获取当前物模型中该属性的值
    String identifier = "xxx";
    LinkKit.getInstance().getDeviceThing().getPropertyValue(identifier);
    
    // 获取默认模块(非用户自定义模块)的属性列表
    LinkKit.getInstance().getDeviceThing().getProperties()
                    

设备事件

设备事件上报

HashMap<String, ValueWrapper> hashMap = new HashMap<>();
// TODO 用户根据实际情况设置
// hashMap.put("ErrorCode", new ValueWrapper.IntValueWrapper(0));
OutputParams params = new OutputParams(valueWrapperMap);
LinkKit.getInstance().getDeviceThing().thingEventPost(identity, params, new IPublishResourceListener() {
    public void onSuccess(String resId, Object o) {
        // 事件上报成功
    }

    public void onError(String resId, AError aError) {
        // 事件上报失败
    }
});
                    

设备服务

  • 设备服务获取 Service 定义参见 Service API Reference

    //获取默认模块(非用户自定义模块)的服务列表
    LinkKit.getInstance().getDeviceThing().getServices()
                        
  • 获取默认模块(非用户自定义模块)的事件列表
    LinkKit.getInstance().getDeviceThing().getEvents()
  • 设备服务调用监听:云端在添加设备服务时,需设置该服务的调用方式,由Service中的callType 字段表示。同步服务调用时callType="sync";异步服务调用callType="async"。设备属性设置和获取也是通过服务调用监听方式实现云端服务的下发。

    • 异步服务调用设备先注册服务的处理监听器,当云端触发异步服务调用的时候,下行的请求会到注册的监听器中。一个设备会有多种服务,通常需要注册所有服务的处理监听器。onProcess 是设备收到的云端下行的服务调用,第一个参数是需要调用服务对应的 identifier,用户可以根据 identifier (identifier 是云端在创建属性或事件或服务的时候的标识符,可以在云端产品的功能定义找到每个属性或事件或服务对应的identifier)做不同的处理。云端调用设置服务的时候,设备需要在收到设置指令后,调用设备执行真实操作,操作结束后上报一条属性状态变化的通知。

      // 用户可以根据实际情况注册自己需要的服务的监听器
      List<Service> srviceList = LinkKit.getInstance().getDeviceThing().getServices();
      for (int i = 0; srviceList != null && i < srviceList.size(); i++) {
          Service service = srviceList.get(i);
          LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
      }
      // 服务处理的handler
      private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
          public void onProcess(String identify, Object result, ITResResponseCallback itResResponseCallback) {
              ALog.d(TAG, "onProcess() called with: s = [" + identify + "], o = [" + result + "], itResResponseCallback = [" + itResResponseCallback + "]");
              ALog.d(TAG, "收到云端异步服务调用 " + identify);
              try {
                  if (SERVICE_SET.equals(identify)) {
                      // TODO  用户按照真实设备的接口调用  设置设备的属性
                      // 设置完真实设备属性之后,上报设置完成的属性值
                      // 用户根据实际情况判断属性是否设置成功,这里测试直接返回成功
                      boolean isSetPropertySuccess = true;
                      if (isSetPropertySuccess) {
                          if (result instanceof InputParams) {
                              Map<String, ValueWrapper> data = (Map<String, ValueWrapper>) ((InputParams) result).getData();
          //                        data.get()
                              ALog.d(TAG, "收到异步下行数据 " + data);
                              // 响应云端,接收数据成功
                              itResResponseCallback.onComplete(identify, null, null);
                          } else {
                              itResResponseCallback.onComplete(identify, null, null);
                          }
                      } else {
                          AError error = new AError();
                          error.setCode(100);
                          error.setMsg("setPropertyFailed.");
                          itResResponseCallback.onComplete(identify, new ErrorInfo(error), null);
                      }
      
                  } else if (SERVICE_GET.equals(identify)) {
                      //  初始化的时候将默认值初始化传进来,物模型内部会直接返回云端缓存的值
      
                  } else {
                      // 根据不同的服务做不同的处理,跟具体的服务有关系
                      ALog.d(TAG, "用户根据真实的服务返回服务的值,请参照set示例");
                      OutputParams outputParams = new OutputParams();
          //                    outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                      itResResponseCallback.onComplete(identify, null, outputParams);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  ALog.d(TAG, "TMP 返回数据格式异常");
              }
          }
      
          public void onSuccess(Object o, OutputParams outputParams) {
              ALog.d(TAG, "onSuccess() called with: o = [" + o + "], outputParams = [" + outputParams + "]");
              ALog.d(TAG, "注册服务成功");
          }
      
          public void onFail(Object o, ErrorInfo errorInfo) {
              ALog.d(TAG, "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
              ALog.d(TAG, "注册服务失败");
          }
          };
                                  
    • 同步服务调用:同步服务调用是一个 RRPC调用。用户可以注册一个下行数据监听,当云端触发服务调用时,可以在onNotify收到云端的下行服务调用。收到云端的下行服务调用之后,用户根据实际服务调用对设备做服务处理,处理之后需要回复云端的请求,即发布一个带有处理结果的请求到云端。当前版本添加了支持使用自定义RRPC,云端的同步服务属性下行将走自定义RRPC通道下行,用户在升级SDK之后要注意这个改动点。
      if (CONNECT_ID.equals(connectId) && !TextUtils.isEmpty(topic) &&
              topic.startsWith("/ext/rrpc/")) {
          ALog.d(TAG, "收到云端自定义RRPC下行");
          //                    ALog.d(TAG, "receice Message=" + new String((byte[]) aMessage.data));
          // 服务端返回数据示例  {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"}
          MqttPublishRequest request = new MqttPublishRequest();
          // 支持 0 和 1, 默认0
          //                request.qos = 0;
          request.isRPC = false;
          request.topic = topic.replace("request", "response");
          String[] array = topic.split("/");
          String resId = array[3];
          request.msgId = resId;
          // TODO 用户根据实际情况填写
          request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
          //                    aResponse.data =
          LinkKit.getInstance().publish(request, new IConnectSendListener() {
              @Override
              public void onResponse(ARequest aRequest, AResponse aResponse) {
                  ALog.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + aResponse + "]");
              }
              @Override
              public void onFailure(ARequest aRequest, AError aError) {
                  ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
              }
          });
      }