物模型开发
物模型是阿里云物联网平台为产品定义的数据模型。您可以通过Android Link SDK,实现设备端上报属性和事件,并接收物联网平台发送的设置属性和调用服务的指令。
背景信息
物联网平台物模型功能的更多信息,请参见什么是物模型。
物模型数据格式的更多信息,请参见设备属性、事件、服务。
使用说明
调用下文提及的物模型相关接口后,回调中onSuccess
仅代表对应消息从设备发出成功,不代表消息对应的任务执行成功。设备执行业务逻辑请勿依赖onSuccess
。
Android Link SDK中,通过
getDeviceThing()
,获取的物模型对象即为IThing。IThing的详细说明,请参见 IThing ApiReference。Android Link SDK默认未开启物模型功能,如需使用,请参见一机一密设备认证方式的示例代码Step 5。
调用物模型接口后,如果您需根据物模型指令的执行结果编写业务的处理逻辑,请参考Demo的
InitManager.java
类中的函数IConnectNotifyListener
接口onNotify
,处理下行消息。具体代码实现请参见Demo中的
TSLActivity.java
。
设备上报属性
上报属性:
// 设备上报 Map<String, ValueWrapper> reportData = new HashMap<>(); // identifier为物联网平台定义的属性标识符,valueWrapper为属性的值 // ValueWrapper valueWrapper = new ValueWrapper.BooleanValueWrapper(1); //以布尔型变量值1为例 // reportData.put(identifier, valueWrapper); // 参考示例,更多使用可参考Demo LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() { @Override public void onSuccess(String alinkId, Object o) { // 消息从设备发出成功 // alinkId表示该消息的messageId } public void onError(String alinkId, AError aError) { // 属性上报失败 // alinkId表示该消息的messageId } });
说明从1.7.3.1版本开始,
thingPropertyPost
的回调接口通过alinkId
字段透出当前所发送的上行消息的ID。如果要观察设备上报的属性消息是否已到达云端,可以在订阅
/sys/${productKey}/${deviceName}/thing/event/property/post_reply
消息后,关注IConnectNotifyListener
类(参考Demo的InitManager.java
)的接口onNotify
。该接口会透出reply
消息的alinkId
,如果上下行消息的alinkId
一致,表示上行消息已经被服务端处理。
获取属性:
获取的是缓存在设备本地的属性数据,不是云端实时的属性数据。
// 通过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 alinkId, Object o) {
// 消息从设备发出成功
// alinkId表示该消息的messageId
}
public void onError(String alinkId, AError aError) {
// 事件上报失败
// alinkId表示该消息的messageId
}
});
从1.2.3版本开始,
thingEventPost
的回调接口通过alinkId
字段透出当前所发送的上行消息的ID。如果要观察设备上报的事件消息是否已到达云端,可以在订阅
/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply
消息后,关注IConnectNotifyListener
类(参考Demo的InitManager.java
)的接口onNotify
。该接口会透出reply
消息的alinkId
,如果上下行消息的alinkId
一致,表示上行消息已经被服务端处理。
获取默认模块(非用户自定义模块)的事件列表:
获取的是设备本地的事件,不是上报到物联网平台的实时事件。
LinkKit.getInstance().getDeviceThing().getEvents()
云端下发属性和服务
设备调用服务获取Service的定义,请参见 Service API Reference。
获取默认模块(非用户自定义模块)的服务列表
LinkKit.getInstance().getDeviceThing().getServices()
设备的服务调用支持同步和异步两种方式。设备属性的设置和获取也是通过该服务调用的监听方式,实现物联网平台服务的下发。
异步调用
设置方法
callType="async"
设备注册服务的处理监听器,当物联网平台触发异步服务调用时,下行的请求会到注册的监听器中。
onProcess
为设备收到的云端下行的服务调用。其中,第一个参数为需调用服务对应的identifier。您可根据identifier做不同的业务处理。identifier为服务的标识符,更多信息,请参见标识符。
设备收到物联网平台的下行服务调用后,根据指令执行对应操作,操作结束后上报一条属性状态变化的通知。
相关代码
// 您可以根据实际情况注册所需的服务监听器 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等类型 } }
同步调用
设置方法
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等类型 } }
模块化物模型
使用说明
只有iot-device-manager的1.7.5.2及以上版本支持模块化物模型。
在物模型默认的模块中,属性、事件、服务的identifer不用加前缀。例如名为
lightSwitch
的属性,identifer就是lightSwitch
。在用户自定义的模块中,属性、事件、服务的identifer要加模块名为前缀。例如
myBlock
模块中的lightSwitch
属性,identifer要写成myBlock:lightSwitch
。
模块化物模型属性的上报
以上报myBlock
模块中的lightSwitch
属性为例:
Map<String, ValueWrapper> reportData = new HashMap<>();
// identifier为物联网平台定义的属性的标识符,valueWrapper为属性的值
String identifier = "myBlock:lightSwitch";
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) {
// 属性上报失败
}
});
模块化物模型事件的上报
以上报map
模块中的OnDetect
事件为例:
HashMap<String, ValueWrapper> hashMap = new HashMap<>();
hashMap.put("StoreID", new ValueWrapper.StringValueWrapper("1"));
OutputParams params = new OutputParams(hashMap);
LinkKit.getInstance().getDeviceThing().thingEventPost("map:OnDetect", params, new IPublishResourceListener() {
@Override
public void onSuccess(String resId, Object o) { // 事件上报动作成功
}
@Override
public void onError(String resId, AError aError) { // 事件上报失败
}
});
模块化服务的注册
用户自定义模块中的服务要先向SDK注册,才能监听到相应的回调,以map
模块中的VehDtcService
服务为例,需要通过如下方式订阅:
thing.setServiceHandler("map:VehDtcService", resRequestHandler);
其中resRequestHandler
是物模型报文处理handler
的实例,请参见demo中的TSLActivity.java
。