1. 概述
“设备可以使用物模型功能,实现属性上报(如上报设备状态)、事件上报(上报设备异常或错误)和服务调用(通过云端调用设备提供的服务)。”[1]
用户可在设备上安装Link Kit SDK,通过Link Kit SDK实现属性上报、事件上报,服务定义等功能。同时,用户也可在云端通过IOT云端SDK实现属性设置、服务调用等功能。此外,用户也可以通过自定义MQTT Topic和云端通信。
本文主要采用产品管理高级版,实现属性上报/获得、事件上报以及服务定义/调用。代码源自官方提供的设备端SDK以及云端SDK的DEMO。
2. 架构
工业上使用较常见的场景是在工控机通用操作系统上安装Link Kit SDK与云端进行通讯。
图 1 在通用OS上物模型样例架构
3. 功能
3.1. 创建产品
在物联网平台中创建产品Robot(高级版),并在产品的【功能定义】中添加属性、事件和服务,详情参见官方帮助。
图 2 属性、事件和服务的定义
图 3 自定义事件
图 4 事件参数
图 5 服务定义
3.2. 添加设备
在物联网平台中创建设备robot,详情参见官方帮助。
3.3. 设备端开发
3.3.1. 下载Demo
在阿里云帮助文档“设备接入Link Kit SDK”[2]中下载Java SDK Demo程序。
l 物联网平台产品文档:【阿里云物联网平台】-【设备端开发指南】-【下载设备端SDK】
l 下载源码后导入IDE
3.3.2. 修改Demo
(1) device_id.json
修改device_id.json文件,填写三元组:
{ "productKey": "a1l3AKuGZ**", "deviceName": "robot", "productSecret":"xLDfQY1XTYru****", "deviceSecret": "kUbuNQvdLRDvlJtiGkuOk95SLGXm****", } |
(2) HelloWorld.java
在HelloWorld.java文件中修改executeScheduler方法,添加test();
public void executeScheduler(DeviceInfoData deviceInfoData) { thingTestManager.readData(System.getProperty("user.dir") + "/test_case.json"); thingTestManager.setServiceHandler(); test(); } |
(3) HelloWorld.java
test()分三部分,分别是:
l 属性上报:设备属性上报云端物模型
private void test() { // (1)设备属性上报云端物模型
// 设备属性上报值 Map<String, ValueWrapper> reportData = new HashMap<String, ValueWrapper>(); reportData.put("myname", new ValueWrapper.StringValueWrapper("shoen")); // identifier 是云端定义的属性的唯一标识,valueWrapper是属性的值 reportData.put("myage", new ValueWrapper.IntValueWrapper(20));
// 设备属性上报和回调 LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() { public void onSuccess(String s, Object o) { // 属性上报成功 } public void onError(String s, AError aError) { // 属性上报失败 } }); |
l 属性获取:从云端物模型获取设备属性
// (2)从云端物模型获取设备属性,根据 identifier 获取当前物模型中该属性的值 String identifier = "myname"; String myname=(String)LinkKit.getInstance().getDeviceThing().getPropertyValue(identifier).getValue(); ALog.d("helloTag:","shoen:"+myname);
String identifier1 = "myage"; int myage=(Integer)LinkKit.getInstance().getDeviceThing().getPropertyValue(identifier1).getValue(); ALog.d("helloTag:","age:"+myage); |
l 事件上报:设备事件上报云端
// (3)设备事件上报云端 HashMap<String, ValueWrapper> valueWrapperMap = new HashMap<String, ValueWrapper>();; String identity = "myevent";
valueWrapperMap.put("p1", new ValueWrapper.IntValueWrapper(50)); // 参考示例,更多使用可参考demo OutputParams params = new OutputParams(valueWrapperMap); LinkKit.getInstance().getDeviceThing().thingEventPost(identity, params, new IPublishResourceListener() { public void onSuccess(String resId, Object o) { // 事件上报成功 ALog.d(TAG, "onSuccess() called with: s = [" + resId + "], o = [" + o + "]"); }
public void onError(String resId, AError aError) { // 事件上报失败 ALog.w(TAG, "onError() called with: s = [" + resId + "], aError = [" + aError.toString() + "]"); } }); |
l 服务:设备先注册服务的处理监听器
// (4)设备先注册服务的处理监听器 ThingSample ts=new ThingSample(pk, dn); ts.setServiceHandler(); } |
(4) ThingSample.java
l 服务定义:定义可供云端调研的服务
l 在mCommonHandler方法中添加如下代码:
} else if (SERVICE_GET.equals(identify)) { // 初始化的时候将默认值初始化传进来,物模型内部会直接返回云端缓存的值 } else if ("myscore".equals(identify)) { /// 响应云端SDK的myscore服务调用 ALog.d(TAG, "响应云端SDK的myscore服务调用"); OutputParams outputParams = new OutputParams(); outputParams.put("out1", new ValueWrapper.IntValueWrapper(50)); itResResponseCallback.onComplete(identify, null, outputParams); } else { |
3.4. 云端开发
3.4.1. 下载Demo
在github上下载IoT套件服务端API使用demo [3]
l 【阿里云物联网平台】-【云端开发指南】-【云端SDK参考】- 【SDK下载】
l 下载源码后导入IDE
3.4.2. 修改Demo
(1) Test.java
l 修改main方法
l 属性设置:云端SDK直接设置设备属性
public static void main(String[] args) throws ClientException { String accessKey = "LTAIUa25no******"; String accessSecret = "1ktxeXGKyFyiOxiMmb************"; DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", "Iot", "iot.cn-shanghai.aliyuncs.com"); IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKey, accessSecret); DefaultAcsClient client = new DefaultAcsClient(profile);
// (1) 云端SDK直接设置设备属性 SetDevicePropertyRequest request = new SetDevicePropertyRequest(); request.setProductKey("a1l3AKuGZMp"); request.setDeviceName("robot"); JSONObject itemJson = new JSONObject(); itemJson.put("myage", 2); request.setItems(itemJson.toString());
try { SetDevicePropertyResponse response = client.getAcsResponse(request); System.out.println(response.getRequestId() + ", success: " + response.getSuccess()); } catch (ClientException e) { e.printStackTrace(); } |
l 修改main方法
l 服务调用:云端SDK调用设备端服务
//(2)云端SDK调用设备端服务 InvokeThingServiceRequest request1=new InvokeThingServiceRequest(); request1.setProductKey("a1l3AKuGZMp"); request1.setDeviceName("robot");
request1.setIdentifier("myscore"); request1.setArgs("{\"in1\":1}"); //request1.setArgs("{\"LightStatus\":1,\"LightNo\":2}"); try { InvokeThingServiceResponse response = client.getAcsResponse(request1); if (response.getSuccess()) { System.out.println("调用成功"); } else { System.out.println("error:" + response.getErrorMessage()); } } catch (ClientException e) { e.printStackTrace(); } } |
3.5. 测试运行
先执行设备端程序,在云端设备显示“在线”后,查看设备属性值以及设备事件上报结果。然后,再执行云端程序,查看服务调用和属性设置结果。
3.5.1. 设备属性上报
查看设备属性值。
图 6 设备属性
3.5.2. 设备事件上报
图 7 设备事件
3.5.3. 云端服务调用和云端属性设置
图 8 云端服务
图 9 云端属性
3.5.4. 云端调用服务返回值
l 参考帮助文件[4]介绍的样例实现:采用服务端订阅的方式获得云端调用设备端服务的返回参数。
l 返回:
topic=/a1l3AKuGZMp/robot/thing/downlink/reply/message
payload={"iotId":"IaCkVvrHpvXBFqXWteqJ0010a87900","code":200,"data":{"out1":50},"requestId":"234609380","topic":"/sys/a1l3AKuGZMp/robot/thing/service/myscore_reply","source":"DEVICE","gmtCreate":1547548002868,"productKey":"a1l3AKuGZMp","deviceName":"robot"}
generateTime=1547548002869
3.5.5. 数据转发获得属性
l 物模型中的属性可通过规则引擎转发至Datahub,通过Datahub查看属性值。
l SELECT items.myname.value as name, items.myage.value as age FROM "/sys/a1l3AKuGZMp/robot/thing/event/property/post"
图 10 规则引擎的设置
3.6. 小结
试用过程中,云端SDK读取设备属性仍有问题,样例中的QueryDevicePropRequest返回错误的属性值,帮助也不完善,的确很有“开源的味道”,希望IOT团队能快速完善SDK,提供优质的API。
目前,在我们的实际工程中,一般使用“服务端订阅的方式”[4]或者通过规则引擎“数据转发”两种方式获得设备的属性值或者调用服务的返回值。
参考文献
[1] 物模型开发[EB/OL]. https://help.aliyun.com/document_detail/97333.html.
[2] 设备接入Link Kit SDK[EB/OL]. https://help.aliyun.com/document_detail/97333.html.
[3] IoT套件服务端API使用demo[EB/OL]. https://github.com/aliyun/iotx-api-demo.
[4] 服务端订阅[EB/OL]. https://help.aliyun.com/document_detail/89906.html.