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]
lhttp://gaic.alicdn.com/ztms/java-iot-device-sdk-demo-v1130/JavaLinkKitDemo.zip?spm=a2c4g.11186623.2.14.2fdd1058TJhODe&file=JavaLinkKitDemo.zip
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 查看属性值.
lSELECT 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.
来源: https://yq.aliyun.com/articles/687093