物模型是阿里云物联网平台为产品定义的数据模型。您可以通过Android Link SDK,实现设备端上报属性和事件,并接收物联网平台发送的设置属性和调用服务的指令。

背景信息

使用说明

注意

调用下文提及的物模型相关接口后,回调中onSuccess仅代表对应消息从设备发出成功,不代表消息对应的任务执行成功。

设备执行业务逻辑请勿依赖onSuccess

  • Android Link SDK中,通过getDeviceThing(),获取的物模型对象即为IThingIThing的详细说明,请参见 IThing ApiReference
  • Android Link SDK默认未开启物模型功能,如需使用,请参见认证与连接后续步骤
  • 调用物模型接口后,如果您需根据物模型指令的执行结果编写业务的处理逻辑,请在InitManager.java类中的函数 IConnectNotifyListener接口onNotify,处理下行消息。

设备上报属性

  • 上报属性:
    // 设备上报
    Map<String, ValueWrapper> reportData  = new HashMap<>();
    // identifier为物联网平台定义的属性的唯一标识,valueWrapper为属性的值
    // reportData.put(identifier, valueWrapper);  // 参考示例,更多使用可参考Demo 
    LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {
        @Override
        public void onSuccess(String resID, Object o) {
            // 属性上报动作成功
        }
    
        @Override
        public void onError(String resId, AError aError) {
            // 属性上报失败
        }
    });
                
  • 获取属性:
    // 通过identifier获取物模型对应属性的值
    String identifier = "******";
    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(hashMap);
LinkKit.getInstance().getDeviceThing().thingEventPost(identifier, params, new IPublishResourceListener() {
    @Override
    public void onSuccess(String resId, Object o) { // 事件上报动作成功
    }

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

设备服务调用

  • 设备调用服务获取Service的定义,请参见 Service API Reference

  • 您可以通过以下代码,获取设备的所有服务。
    LinkKit.getInstance().getDeviceThing().getServices()
  • 设备的服务调用支持同步和异步两种方式。设备属性的设置和获取也是通过该服务调用的监听方式,实现物联网平台服务的下发。

    调用方式 设置方法 说明
    异步 callType="async"
    • 设备注册服务的处理监听器,当物联网平台触发异步服务调用时,下行的请求会到注册的监听器中。
    • onProcess为设备收到的云端下行的服务调用。其中,第一个参数为需调用服务对应的identifier。您可根据identifier做不同的业务处理。

      identifier为服务的标识符,更多信息,请参见标识符

    • 设备收到物联网平台的下行服务调用后,根据指令执行对应操作,操作结束后上报一条属性状态变化的通知。
    同步 callType="sync"
    • 同步服务调用即为RRPC调用。
    • 您可以注册一个下行数据监听,当云端触发服务调用时,可以在onNotify接收物联网平台的下行服务调用。
    • 设备收到物联网平台的下行服务调用后,根据指令执行对应操作,操作结束后,向物联网平台发送含处理结果的请求。
    说明 新版本的Android Link SDK支持自定义RRPC,如果您的SDK是由低版本升级而来,请注意同步服务属性下行的通道为RRPC。

    相关代码如下:

    • 异步:
      // 您可以根据实际情况注册所需的服务监听器
      LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
      // 服务处理的handler
      private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
          @Override
          public void onProcess(String identify, Object result, ITResResponseCallback itResResponseCallback) {
              // 接受物联网平台的异步服务调用,identify为设备端属性或服务唯一标识,result为下行服务调用数据 
          // iotResResponseCallback 处理完服务调用之后响应,具体使用,请参见Demo代码
              try {
                  if (SERVICE_SET.equals(identify)) { // set 异步服务调用
                      // TODO  根据真实设备的接口调用,设置设备的属性
                      // 设置完真实设备属性之后,上报设置完成的属性值
                      // 根据实际情况判断属性是否设置成功,示例代码直接返回成功
                      boolean isSetPropertySuccess = true;
                      if (isSetPropertySuccess){
                          if (result instanceof InputParams) {
                              Map<String, ValueWrapper> data = (Map<String, ValueWrapper>) ((InputParams) result).getData();
                              // 响应物联网平台,接收数据成功
                              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)){ // get异步服务调用
                      //  初始化的时,传入初始化默认值,物模型内部会直接返回物联网平台缓存的值
      
                  } else { // 定义服务调用
                      // 根据不同的服务做不同的处理,与具体的服务有关
                      OutputParams outputParams = new OutputParams();
      //                    outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                      itResResponseCallback.onComplete(identify,null, outputParams);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          @Override
          public void onSuccess(Object o, OutputParams outputParams) {
             // 服务注册成功tag:您传入的tag,未使用outputParams:异步回调成功的返回数据,outparams等类型
          }
      
          @Override
          public void onFail(Object o, ErrorInfo errorInfo) {
               // 服务注册失败
          }
      };
          
    • 同步:
      if (CONNECT_ID.equals(connectId) && !TextUtils.isEmpty(topic) &&
              topic.startsWith("/ext/rrpc/")) {
          showToast("收到物联网平台自定义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) {
                  Log.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + aResponse + "]");
              }
      
              @Override
              public void onFailure(ARequest aRequest, AError aError) {
                  Log.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
              }
          });
      }