阿里云物联网平台物模型功能测试示例Demo
概述
物模型指将物理空间中的实体数字化,并在云端构建该实体的数据模型。在物联网平台中,定义物模型即定义产品功能。完成功能定义后,系统将自动生成该产品的物模型。物模型描述产品是什么,能做什么,可以对外提供哪些服务。物模型将产品功能类型分为三类:属性、服务、和事件。定义了这三类功能,即完成了物模型的定义。
功能类型 | 说明 |
---|---|
属性(Property) | 一般用于描述设备运行时的状态,如环境监测设备所读取的当前环境温度等。属性支持GET和SET请求方式。应用系统可发起对属性的读取和设置请求。 |
服务(Service) | 设备可被外部调用的能力或方法,可设置输入参数和输出参数。相比于属性,服务可通过一条指令实现更复杂的业务逻辑,如执行某项特定的任务。 |
事件(Event) | 设备运行时的事件。事件一般包含需要被外部感知和处理的通知信息,可包含多个输出参数。如,某项任务完成的信息,或者设备发生故障或告警时的温度等,事件可以被订阅和推送。 |
使用: 设备端可以上报属性和事件;云端可以向设备端发送设置属性和调用服务的指令。
Step By Step
1、产品物模型model.json(替换产品productKey导入即可)
{ "schema":"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json", "profile":{ "productKey":"a1qLU******" }, "properties":[ { "identifier":"Temperature", "name":"温度", "accessMode":"rw", "desc":"电机工作温度", "required":false, "dataType":{ "type":"float", "specs":{ "min":"-55", "max":"200", "unit":"℃", "step":"0.1" } } } ], "events":[ { "identifier":"post", "name":"post", "type":"info", "required":true, "desc":"属性上报", "method":"thing.event.property.post", "outputData":[ { "identifier":"Temperature", "name":"温度", "dataType":{ "type":"float", "specs":{ "min":"-55", "max":"200", "unit":"℃", "step":"0.1" } } } ] }, { "identifier":"event1", "name":"异常事件", "type":"info", "required":false, "method":"thing.event.event1.post", "outputData":[ { "identifier":"event1", "name":"事件参数1", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"100", "step":"1" } } } ] } ], "services":[ { "identifier":"set", "name":"set", "required":true, "callType":"async", "desc":"属性设置", "method":"thing.service.property.set", "inputData":[ { "identifier":"Temperature", "name":"温度", "dataType":{ "type":"float", "specs":{ "min":"-55", "max":"200", "unit":"℃", "step":"0.1" } } } ], "outputData":[ ] }, { "identifier":"get", "name":"get", "required":true, "callType":"async", "desc":"属性获取", "method":"thing.service.property.get", "inputData":[ "Temperature" ], "outputData":[ { "identifier":"Temperature", "name":"温度", "dataType":{ "type":"float", "specs":{ "min":"-55", "max":"200", "unit":"℃", "step":"0.1" } } } ] }, { "identifier":"addFuctionServiceAsync", "name":"异步加法服务", "required":false, "callType":"async", "method":"thing.service.addFuctionServiceAsync", "inputData":[ { "identifier":"add1", "name":"加数1", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"100", "step":"1" } } }, { "identifier":"add2", "name":"加数2", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"100", "step":"1" } } } ], "outputData":[ { "identifier":"result", "name":"结果", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"200", "step":"1" } } } ] }, { "identifier":"addFuctionServiceSync", "name":"加法服务", "required":false, "callType":"sync", "desc":"同步功能", "method":"thing.service.addFuctionServiceSync", "inputData":[ { "identifier":"add2", "name":"加数2", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"100", "step":"1" } } }, { "identifier":"add1", "name":"加数1", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"100", "step":"1" } } } ], "outputData":[ { "identifier":"result", "name":"计算结果", "dataType":{ "type":"int", "specs":{ "min":"1", "max":"200", "step":"1" } } } ] } ] }
2、设备端Code Sample(基于开源Java MQTT Client)
import com.alibaba.fastjson.JSONObject; import com.alibaba.taro.AliyunIoTSignUtil; import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import java.util.HashMap; import java.util.Map; public class IoTThingTest { public static String productKey = "a1qLU******"; public static String deviceName = "device1"; public static String deviceSecret = "cA9wzIM6bL2QI6DgAaSO0FPg********"; public static String regionId = "cn-shanghai"; // 物模型-属性上报topic private static String pubTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/property/post"; // 物模型-属性响应topic private static String subTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/property/post_reply"; // 物模型-事件上报topic private static String eventPubTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/event1/post"; // 物模型-事件上报响应topic private static String eventSubTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/event1/post_reply"; private static MqttClient mqttClient; public static void main(String [] args){ // 初始化Client initAliyunIoTClient(); try { mqttClient.subscribe(subTopic); // 订阅Topic mqttClient.subscribe(eventSubTopic); } catch (MqttException e) { System.out.println("error:" + e.getMessage()); e.printStackTrace(); } // 设置订阅监听 mqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable throwable) { System.out.println("connection Lost"); } @Override public void messageArrived(String s, MqttMessage mqttMessage) throws Exception { System.out.println("Sub message"); System.out.println("Topic : " + s); System.out.println(new String(mqttMessage.getPayload())); //打印输出消息payLoad // 服务调用处理 if (s.contains("Async") || s.contains("rrpc")) { String content = new String((byte[]) mqttMessage.getPayload()); System.out.println("服务请求Topic:" + s); System.out.println("服务指令:" + content); JSONObject request = JSONObject.parseObject(content); JSONObject params = request.getJSONObject("params"); if (!params.containsKey("add1")) { // 检查入参 System.out.println("不包含参数add1"); return; } Integer input1 = params.getInteger("add1"); // 获取入参 Integer input2 = params.getInteger("add2"); // 获取入参 JSONObject response = new JSONObject(); JSONObject data = new JSONObject(); data.put("result", input1 + input2); response.put("id", request.get("id")); response.put("code", 200); response.put("data", data); String responseTopic = s; // 服务响应 if (s.contains("rrpc")) { // 同步服务调用响应Topic responseTopic = s.replace("request", "response"); } else { // 异步服务调用响应Topic responseTopic = responseTopic + "_reply"; } MqttMessage message1 = new MqttMessage(response.toString().getBytes("utf-8")); System.out.println("responseTopic: " + responseTopic); mqttClient.publish(responseTopic, message1); } } @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { } }); // 属性上报 postDeviceProperties(); // 事件上报 postDeviceEvent(); } /** * 初始化 Client 对象 */ private static void initAliyunIoTClient() { try { // 构造连接需要的参数 String clientId = "java" + System.currentTimeMillis(); Map<String, String> params = new HashMap<>(16); params.put("productKey", productKey); params.put("deviceName", deviceName); params.put("clientId", clientId); String timestamp = String.valueOf(System.currentTimeMillis()); params.put("timestamp", timestamp); // cn-shanghai String targetServer = "tcp://" + productKey + ".iot-as-mqtt."+regionId+".aliyuncs.com:1883"; String mqttclientId = clientId + "|securemode=3,signmethod=hmacsha1,timestamp=" + timestamp + "|"; String mqttUsername = deviceName + "&" + productKey; String mqttPassword = AliyunIoTSignUtil.sign(params, deviceSecret, "hmacsha1"); connectMqtt(targetServer, mqttclientId, mqttUsername, mqttPassword); } catch (Exception e) { System.out.println("initAliyunIoTClient error " + e.getMessage()); } } public static void connectMqtt(String url, String clientId, String mqttUsername, String mqttPassword) throws Exception { MemoryPersistence persistence = new MemoryPersistence(); mqttClient = new MqttClient(url, clientId, persistence); MqttConnectOptions connOpts = new MqttConnectOptions(); // MQTT 3.1.1 connOpts.setMqttVersion(4); connOpts.setAutomaticReconnect(false); connOpts.setConnectionTimeout(10); // connOpts.setCleanSession(true); connOpts.setCleanSession(false); connOpts.setUserName(mqttUsername); connOpts.setPassword(mqttPassword.toCharArray()); connOpts.setKeepAliveInterval(60); mqttClient.connect(connOpts); } /** * 事件上报 */ private static void postDeviceEvent() { try { //上报数据 //高级版 物模型-属性上报payload System.out.println("事件上报"); String payloadJson = "{\"params\":{\"event1\":23}}"; MqttMessage message = new MqttMessage(payloadJson.getBytes("utf-8")); message.setQos(1); mqttClient.publish(eventPubTopic, message); } catch (Exception e) { System.out.println(e.getMessage()); } } /** * 汇报属性 */ private static void postDeviceProperties() { try { //上报数据 //高级版 物模型-属性上报payload System.out.println("上报属性值"); String payloadJson = "{\"params\":{\"Temperature\":13}}"; MqttMessage message = new MqttMessage(payloadJson.getBytes("utf-8")); message.setQos(1); mqttClient.publish(pubTopic, message); } catch (Exception e) { System.out.println(e.getMessage()); } } }
3、启动设备查看属性及事件上报情况
- 3.1 服务端情况
- 3.2 设备端reply情况
上报属性值 事件上报 Sub message Topic : /sys/a1qLU******/device1/thing/event/property/post_reply {"code":200,"data":{},"id":"null","message":"success","method":"thing.event.property.post","version":"1.0"} Sub message Topic : /sys/a1qLU******/device1/thing/event/event1/post_reply {"code":200,"data":{},"id":"null","message":"success","method":"thing.event.event1.post","version":"1.0"}
4、异步服务调用
- 4.1 说明
通过InvokeThingService或InvokeThingsService接口调用服务,物联网平台采用异步方式下行推送请求,设备也采用异步方式返回结果。 此时,服务选择为异步调用方式,物联网平台订阅此处的异步响应Topic。异步调用的结果,可以使用规则引擎数据流转功能获取,也可以使用服务端订阅获取。
- 4.2 Open API InvokeThingService
- 4.3 设备端日志
Sub message Topic : /sys/a1qLU******/device1/thing/service/addFuctionServiceAsync {"method":"thing.service.addFuctionServiceAsync","id":"2015524670","params":{"add2":2,"add1":2},"version":"1.0.0"} 服务请求Topic:/sys/a1qLU******/device1/thing/service/addFuctionServiceAsync 服务指令:{"method":"thing.service.addFuctionServiceAsync","id":"2015524670","params":{"add2":2,"add1":2},"version":"1.0.0"} responseTopic: /sys/a1qLU******/device1/thing/service/addFuctionServiceAsync_reply
- 4.4 控制台日志
- 4.5 AMQP 服务端订阅获取的服务响应
Content:{"iotId":"*******","code":200,"data":{"result":4},"requestId":"2009566194","topic":"/sys/*******/device1/thing/service/addFuctionServiceAsync_reply","source":"DEVICE","gmtCreate":1583658474852,"productKey":"a1qLU******","deviceName":"device1"}
5、同步服务调用
- 5.1 说明
通过InvokeThingService或InvokeThingsService接口调用服务,物联网平台直接使用RRPC同步方式下行推送请求。此时,服务选择为同步调用方式,物联网平台订阅RRPC对应Topic。
- 5.2 Open API InvokeThingService
- 5.3 设备端日志
Sub message Topic : /sys/a1qLU******/device1/rrpc/request/1236608506958775809 {"method":"thing.service.addFuctionServiceSync","id":"2015301903","params":{"add2":2,"add1":2},"version":"1.0.0"} 服务请求Topic:/sys/a1qLU******/device1/rrpc/request/1236608506958775809 服务指令:{"method":"thing.service.addFuctionServiceSync","id":"2015301903","params":{"add2":2,"add1":2},"version":"1.0.0"} responseTopic: /sys/a1qLU******/device1/rrpc/response/1236608506958775809
- 5.4 控制台日志
更多参考
设备属性、事件、服务
同步服务调用
基于开源Java MQTT Client的阿里云物联网平台RRPC功能测试
阿里云物联网平台规则引擎综述
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【译】Databricks使用Spark Streaming和Delta Lake对流式数据进行数据质量监控介绍
原文链接:https://databricks.com/blog/2020/03/04/how-to-monitor-data-stream-quality-using-spark-streaming-and-delta-lake.html 在这个一切都需要进行加速的时代,流数据的使用变得越来越普遍。我们经常不再听到客户问:“我可以流式传输这些数据吗?”,更多的是问:“我们能以多快的速度流式传输这些数据?”,而诸如Kafka和Delta Lake之类技术的普及更突显了这一势头。我们认为传统流式数据传输的一种形式是以非常快的速度到达的半结构化或非结构化(例如JSON)数据,通常情况下一批数据的量也比较小。这种形式的工作场景横跨各行各业,举一个这样的客户案例,某个证券交易所和数据提供商,他们负责每分钟流式传输数十万个数据项目,包括股票行
- 下一篇
手把手,教你如何逐步提高JavaScript的编码能力?
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 今天,小芯给大家分享一些提高JavaScript编码能力的应用方法,学习并运用到实践中,你也可以成为编码熟练工哟~ 编辑器 目前,编辑器种类繁多,人们不知道选择哪种编辑器来提高工作效率。 于我而言,除了使用Android Studio或使用Xcode的iOS所需的Android代码外,我大多只使用Visual Studio Code。 这是由Microsoft开发的编辑器。这是Microsoft开发的,听起来不错!!!几乎支持所有语言,无数附加插件,AI代码建议,漂亮的界面和浅色调(不是Sublime Text,但…仍然是浅色?) 过去,我只使用Sublime Text(当时不流行VSCode)。大量的插件(将在下文讨论)为我节省了很多时间,例如自动检测并修复错误,格式代码,git镜头,终端等……,因为不再需要解决编码时常见的小错误。 如果编写PHP,一定会喜欢PHPStorm。如果编写Python,则一定会喜欢PyCharm。毋庸...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- 设置Eclipse缩进为4个空格,增强代码规范
- Mario游戏-低调大师作品
- MySQL8.0.19开启GTID主从同步CentOS8
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果