查看: 16341|回复: 2

[7月赛] 【开源盛世】Java端获取OneNet平台数据及源码学习经验分享

[复制链接]

1

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2017-7-31 21:42:55 | 显示全部楼层 |阅读模式
本帖最后由 cqugp 于 2017-8-1 09:57 编辑


作为2017年的中移物联网实习生,有幸接触到了OneNet平台,在开发小组中负责应用端的开发(即对OneNet平台的数据获取、处理以及下达命令等)。

##########################################################################################################################

直接上一个OnetNet的JavaSDK github的地址https://github.com/cm-heclouds/JAVA-HTTP-SDK,里面有部分供学习的例子。当然,笔者在使用SDK时,结合实际需求,发现了SDK中存在的一些小瑕疵(有可能故意不完整,让我们学会不要总是“拿来主义”,而是根据自己的需求动态的修改源码)。

特别申明一下,笔者下载的SDK时间为2017年7月21日,若有同学发现目前SDK已经修改,则自动无视此贴。发帖时间为2017年7月31日,笔者看了下github上的源码,在本帖提到的代码是无修改的。


那么接下来就是笔者的一些学习经验


1. 在测试ApiTest.java类的testGetDatapointsApi()方法时,当仅设置start_time 和 end_time 时,若此时间段无数据,理应返回空数据,却出现了Unrecognized field, not marked as ignorable 错误。该错误的意思是说,不能够识别的字段没有标识为可忽略。出现该问题的原因就是JSON中包含了Java没有的属性。

问题当设备离线/掉线一段时间,查询这时间段 某数据流 的所有数据时(此时间段的数据未由设备端上传到OneNet平台),SDK源码的示例报此错误。

解决办法在DatapointsList类上添加 @JsonIgnoreProperties(ignoreUnknown = true)此时再出现上述特殊情况,则会返回 data为null,也正是我们所需要的返回结果

  1. @JsonIgnoreProperties(ignoreUnknown = true)
  2. public class DatapointsList {
  3.         
复制代码

2. 依然是测试ApiTest.java类的testGetDatapointsApi()方法,在其方法体中存在一个 GetDatapointsListApi(...),其中一个参数为cursor。其作用是在某个时间段内需要多次查询时,每次成功查询后结果会返回一个cursor,进行下一次再次查询时,只需要更新cursor就可以获取在某个时间段内紧连的数据。听上去很拗口吧,简而言之,当一个时间段内的数据量太大时(默认一次最多返回6000条数据),需要对此时间段内的数据进行分段获取,当第一段被查找成功返回时,会返回第二段的cursor,此时要获取cursor在进行下一段的查询,以此类推。

由于源码的注解解释得过于简单,笔者打印 response.getJson(),发现cursor字段并不是Integer类型,应该改为String类型!!!

  1. {"errno":0,"error":"succ","data":{<font color="#ff0000"><b>"cursor":"91408_9726896_1500708255375"</b></font>,"count":100,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:00:15.494","value":55.073345},{"at":"2017-07-22 15:00:30.202","value":54.066265},{"at":"2017-07-22 15:00:45.412","value":54.691875},{"at":"2017-07-22 15:01:00.516","value":54.958904},{"at":"2017-07-22 15:01:15.621","value":55.103863},{"at":"2017-07-22 15:01:30.333","value":55.759995},....
复制代码

问题:传入cursor参数值非法

解决办法:将GetDatapointsListApi()类中的cursor字段的类型由Integer改为String,并修改相应的构造函数

  1. /**
  2.          * 数据点查询
  3.          * @param datastreamIds:查询的数据流,多个数据流之间用逗号分隔(可选),String
  4.          * @param start:提取数据点的开始时间(可选),String
  5.          * @param end:提取数据点的结束时间(可选),String
  6.          * @param devId:设备ID,String
  7.          * @param duration:查询时间区间(可选,单位为秒),Integer
  8.          *  start+duration:按时间顺序返回从start开始一段时间内的数据点
  9.          *  end+duration:按时间倒序返回从end回溯一段时间内的数据点
  10.          * @param limit:限定本次请求最多返回的数据点数,0<n<=6000(可选,默认1440),Integer
  11.          * @param cursor:指定本次请求继续从cursor位置开始提取数据(可选),<font color="#ff0000"><b>String</b></font>
  12.          * @param interval:通过采样方式返回数据点,interval值指定采样的时间间隔(可选),Integer
  13.          * @param metd:指定在返回数据点时,同时返回统计结果,可能的值为(可选),String
  14.          * @param first:返回结果中最值的时间点。1-最早时间,0-最近时间,默认为1(可选),Integer
  15.          * @param sort:值为DESC|ASC时间排序方式,DESC:倒序,ASC升序,默认升序,String
  16.          * @param key:masterkey 或者 设备apikey
  17.          */
  18.         public GetDatapointsListApi(String datastreamIds, String start, String end, String devId, Integer duration,
  19.                         Integer limit, String cursor, Integer interval, String metd, Integer first, String sort,String key) {
  20.                 super();
  21.                 this.datastreamIds = datastreamIds;
  22.                 this.start = start;
  23.                 this.end = end;
  24.                 this.devId = devId;
  25.                 this.duration = duration;
  26.                 this.limit = limit;
  27.                 this.cursor = cursor;
  28.                 this.interval = interval;
  29.                 this.metd = metd;
  30.                 this.first = first;
  31.                 this.sort = sort;
  32.                 this.key=key;
  33.                 this.method= Method.GET;
  34.                 this.HttpMethod = new HttpGetMethod(method);
  35. 。。。
  36. }
复制代码


3. 紧接上述问题,当需要获取cursor属性,但是发现DatapointsList类中无cursor字段,也就无法从返回的结果中通过获取对象的属性的方式获取cursor

问题response.getJson()返回的Json无法获取data中的cursor字段

解决办法:在DatapointsList类中添加cursor字段,并且提供相应的getter/setter方法

  1. @JsonProperty("cursor")
  2. private String cursor;

  3.        public String getCursor() {
  4.                     return cursor;
  5.         }
  6.         public void setCursor(String cursor) {
  7.                     this.cursor = cursor;
  8.        }
复制代码


OK,到了这里给出一份简单完整的代码,目的是在一个时间段内,将一个数据流的数据分为几段,每次按照一段21个数据点取(不足21就说明,数据已经取完),以此来实现前端间断请求后台,返回实时监控数据。此时,就需要cursor来帮我们获取分段数据了,来看看简单的实现代码吧.

  1. @Test
  2.         public void testGetDatapointsApi() {
  3.                 String datastreamids = "湿度";
  4.                 String devid = "9726896";
  5.                 String key = "DUBLZYFgE7yDHePh1UB89xzO2BA=";
  6.                 /**
  7.                  * 数据点查询
  8.                  * @param datastreamids:查询的数据流,多个数据流之间用逗号分隔(可选),String
  9.                  * @param start:提取数据点的开始时间(可选),String
  10.                  * @param end:提取数据点的结束时间(可选),String
  11.                  * @param devid:设备ID,String
  12.                  *
  13.                  * @param duration:查询时间区间(可选,单位为秒),Integer
  14.                  *  start+duration:按时间顺序返回从start开始一段时间内的数据点
  15.                  *  end+duration:按时间倒序返回从end回溯一段时间内的数据点
  16.                  *
  17.                  * @param limit:限定本次请求最多返回的数据点数,0<n<=6000(可选,默认1440),Integer
  18.                  * @param cursor:指定本次请求继续从cursor位置开始提取数据(可选),<b style="color: rgb(255, 0, 0);">String</b>
  19.                  * @param interval:通过采样方式返回数据点,interval值指定采样的时间间隔(可选),Integer
  20.                  * @param metd:指定在返回数据点时,同时返回统计结果,可能的值为(可选),String
  21.                  * @param first:返回结果中最值的时间点。1-最早时间,0-最近时间,默认为1(可选),Integer
  22.                  * @param sort:值为DESC|ASC时间排序方式,DESC:倒序,ASC升序,默认升序,String
  23.                  * @param key:masterkey 或者 设备apikey
  24.                  */

  25.                 String cursor = null;
  26.                 do{
  27.                 GetDatapointsListApi api = new GetDatapointsListApi(datastreamids,
  28.                                         "2017-07-22T15:00:09", // start_time
  29.                                         "2017-07-22T15:57:35", // end_time
  30.                                         devid,
  31.                                         null,                                    // duration
  32.                                         21,                                    // limit
  33.                                         cursor,                            // cursor
  34.                                         null,                  // interval
  35.                                         null,                  // metd
  36.                                         null,                  // first
  37.                                         null,                  // sort
  38.                                         key);
  39.             BasicResponse<DatapointsList>  response = api.executeApi();
  40.                 DatapointsList dal = response.getData();
  41.                 cursor = dal.getCursor();
  42. //                System.out.println(cursor);
  43.                 System.out.println(response.getJson());
  44.                 System.out.println("#########################################");
  45.                 }while(cursor!=null);
  46.                

  47.                
  48.         }
复制代码

再来看看结果如何~

  1. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500707080064","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:00:15.494","value":55.073345},{"at":"2017-07-22 15:00:30.202","value":54.066265},{"at":"2017-07-22 15:00:45.412","value":54.691875},{"at":"2017-07-22 15:01:00.516","value":54.958904},{"at":"2017-07-22 15:01:15.621","value":55.103863},{"at":"2017-07-22 15:01:30.333","value":55.759995},{"at":"2017-07-22 15:01:45.540","value":55.729477},{"at":"2017-07-22 15:02:00.143","value":55.340378},{"at":"2017-07-22 15:02:15.246","value":55.965988},{"at":"2017-07-22 15:02:30.453","value":55.340378},{"at":"2017-07-22 15:02:45.163","value":55.668442},{"at":"2017-07-22 15:03:00.268","value":55.073345},{"at":"2017-07-22 15:03:32.781","value":54.981792},{"at":"2017-07-22 15:03:36.596","value":55.01231},{"at":"2017-07-22 15:03:41.412","value":54.981792},{"at":"2017-07-22 15:03:45.518","value":54.745281},{"at":"2017-07-22 15:04:00.622","value":55.157269},{"at":"2017-07-22 15:04:15.223","value":55.073345},{"at":"2017-07-22 15:04:30.040","value":54.951275},{"at":"2017-07-22 15:04:30.646","value":54.920757},{"at":"2017-07-22 15:04:34.354","value":54.951275}],"id":"湿度"}]}}
  2. #########################################
  3. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500707385404","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:04:40.064","value":54.920757},{"at":"2017-07-22 15:04:45.274","value":54.798687},{"at":"2017-07-22 15:05:00.378","value":54.920757},{"at":"2017-07-22 15:05:15.483","value":54.447735},{"at":"2017-07-22 15:05:30.191","value":54.028118},{"at":"2017-07-22 15:05:45.399","value":54.180706},{"at":"2017-07-22 15:06:00.503","value":56.263535},{"at":"2017-07-22 15:06:15.607","value":54.325665},{"at":"2017-07-22 15:06:30.317","value":54.417217},{"at":"2017-07-22 15:06:45.526","value":54.150188},{"at":"2017-07-22 15:07:00.631","value":54.325665},{"at":"2017-07-22 15:07:15.232","value":53.524578},{"at":"2017-07-22 15:07:30.443","value":53.730572},{"at":"2017-07-22 15:07:45.152","value":53.555096},{"at":"2017-07-22 15:08:00.256","value":53.669537},{"at":"2017-07-22 15:08:15.360","value":53.997601},{"at":"2017-07-22 15:08:30.569","value":54.531658},{"at":"2017-07-22 15:08:45.274","value":54.623211},{"at":"2017-07-22 15:09:00.382","value":53.997601},{"at":"2017-07-22 15:09:15.486","value":54.264629},{"at":"2017-07-22 15:09:30.195","value":54.142559}],"id":"湿度"}]}}
  4. #########################################
  5. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500707700137","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:09:45.404","value":54.562176},{"at":"2017-07-22 15:10:00.508","value":55.988876},{"at":"2017-07-22 15:10:15.113","value":55.660812},{"at":"2017-07-22 15:10:30.333","value":55.218307},{"at":"2017-07-22 15:10:45.538","value":54.623211},{"at":"2017-07-22 15:11:00.135","value":54.325665},{"at":"2017-07-22 15:11:15.238","value":54.348553},{"at":"2017-07-22 15:11:30.445","value":54.653728},{"at":"2017-07-22 15:11:45.155","value":54.707134},{"at":"2017-07-22 15:12:00.258","value":54.89024},{"at":"2017-07-22 15:12:15.364","value":54.707134},{"at":"2017-07-22 15:12:30.573","value":55.187786},{"at":"2017-07-22 15:12:45.278","value":55.065716},{"at":"2017-07-22 15:13:00.387","value":55.004681},{"at":"2017-07-22 15:13:15.490","value":54.859722},{"at":"2017-07-22 15:13:30.198","value":54.768169},{"at":"2017-07-22 15:13:45.408","value":54.768169},{"at":"2017-07-22 15:14:00.512","value":54.829205},{"at":"2017-07-22 15:14:15.117","value":55.096233},{"at":"2017-07-22 15:14:30.327","value":54.203594},{"at":"2017-07-22 15:14:45.534","value":53.814495}],"id":"湿度"}]}}
  6. #########################################
  7. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500708015371","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:15:00.137","value":53.906048},{"at":"2017-07-22 15:15:15.243","value":54.409588},{"at":"2017-07-22 15:15:30.450","value":55.004681},{"at":"2017-07-22 15:15:45.159","value":53.989971},{"at":"2017-07-22 15:16:00.263","value":54.142559},{"at":"2017-07-22 15:16:15.368","value":54.287518},{"at":"2017-07-22 15:16:30.075","value":54.203594},{"at":"2017-07-22 15:16:45.285","value":54.234112},{"at":"2017-07-22 15:17:00.391","value":54.203594},{"at":"2017-07-22 15:17:15.492","value":54.051006},{"at":"2017-07-22 15:17:30.202","value":54.470623},{"at":"2017-07-22 15:17:45.413","value":55.332748},{"at":"2017-07-22 15:18:00.517","value":56.286423},{"at":"2017-07-22 15:18:15.119","value":54.707134},{"at":"2017-07-22 15:18:30.330","value":54.142559},{"at":"2017-07-22 15:18:45.538","value":53.959454},{"at":"2017-07-22 15:19:00.141","value":54.943645},{"at":"2017-07-22 15:19:15.245","value":54.462994},{"at":"2017-07-22 15:19:30.456","value":54.409588},{"at":"2017-07-22 15:19:45.164","value":54.112041},{"at":"2017-07-22 15:20:00.267","value":54.081524}],"id":"湿度"}]}}
  8. #########################################
  9. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500708330213","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:20:15.371","value":54.493511},{"at":"2017-07-22 15:20:30.081","value":54.081524},{"at":"2017-07-22 15:20:45.291","value":53.75346},{"at":"2017-07-22 15:21:00.393","value":53.63139},{"at":"2017-07-22 15:21:15.498","value":54.974163},{"at":"2017-07-22 15:21:30.207","value":54.768169},{"at":"2017-07-22 15:21:45.415","value":53.989971},{"at":"2017-07-22 15:22:00.519","value":54.257},{"at":"2017-07-22 15:22:15.124","value":54.676617},{"at":"2017-07-22 15:22:30.332","value":54.348553},{"at":"2017-07-22 15:22:45.041","value":54.37907},{"at":"2017-07-22 15:23:00.146","value":53.692425},{"at":"2017-07-22 15:23:15.249","value":53.63139},{"at":"2017-07-22 15:23:30.458","value":54.020489},{"at":"2017-07-22 15:23:45.168","value":54.226482},{"at":"2017-07-22 15:24:00.272","value":54.287518},{"at":"2017-07-22 15:24:15.375","value":53.837383},{"at":"2017-07-22 15:24:30.085","value":53.837383},{"at":"2017-07-22 15:24:45.294","value":53.63139},{"at":"2017-07-22 15:25:00.398","value":53.837383},{"at":"2017-07-22 15:25:15.501","value":53.722942}],"id":"湿度"}]}}
  10. #########################################
  11. {"errno":0,"error":"succ","data":{"cursor":"91408_9726896_1500708645064","count":21,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:25:30.213","value":53.806866},{"at":"2017-07-22 15:25:45.418","value":54.165447},{"at":"2017-07-22 15:26:00.523","value":54.676617},{"at":"2017-07-22 15:26:15.128","value":53.898418},{"at":"2017-07-22 15:26:30.337","value":53.539837},{"at":"2017-07-22 15:26:45.044","value":53.478802},{"at":"2017-07-22 15:27:00.154","value":53.364361},{"at":"2017-07-22 15:27:15.260","value":53.570354},{"at":"2017-07-22 15:27:30.468","value":53.204144},{"at":"2017-07-22 15:27:45.176","value":53.204144},{"at":"2017-07-22 15:28:00.282","value":53.173626},{"at":"2017-07-22 15:28:15.385","value":53.387249},{"at":"2017-07-22 15:28:30.099","value":53.570354},{"at":"2017-07-22 15:28:45.307","value":53.654278},{"at":"2017-07-22 15:29:00.412","value":53.509319},{"at":"2017-07-22 15:29:15.016","value":53.806866},{"at":"2017-07-22 15:29:30.225","value":54.043377},{"at":"2017-07-22 15:29:45.432","value":54.104412},{"at":"2017-07-22 15:30:00.043","value":54.073895},{"at":"2017-07-22 15:30:15.146","value":54.104412},{"at":"2017-07-22 15:30:30.357","value":54.188335}],"id":"湿度"}]}}
  12. #########################################
  13. {"errno":0,"error":"succ","data":{"count":3,"datastreams":[{"datapoints":[{"at":"2017-07-22 15:30:45.064","value":54.104412},{"at":"2017-07-22 15:31:00.168","value":53.982342},{"at":"2017-07-22 15:31:15.274","value":53.921307}],"id":"湿度"}]}}
  14. #########################################
复制代码






讲了这么关于Java的源码分享,可以继续分享通过postman对平台发起请求的一些测试


1. HTTP/RESTfulAPI 上传数据


HTTP/RESTfulAPI 上传数据

HTTP/RESTfulAPI 上传数据


2. 查看get/URL

格式: http://api.heclouds.com/devices/9751674/datapoints?datastream_id=gp&start=2015-12-02T14:01:46&limit=3  


以json的数据格式上传

以json的数据格式上传


3. 以json的数据格式上传


查看get/URL http://api.heclouds.com/devices/9751674/datapoints?datastream_id=gp&start=2015-12-02T14: ...

查看get/URL http://api.heclouds.com/devices/9751674/datapoints?datastream_id=gp&start=2015-12-02T14: ...


笔者想要分享的暂时就只有这些了,如果没有postman插件的小朋友可以在附件中下载谷歌浏览器助手。使用方法也特别简单、


  • 打开谷歌浏览器
  • 设置---》扩展工具
  • 把附件的文件解压,解压的文件拖进页面当中,设置下主页就OK啦
  • 重启下谷歌浏览器,等待地址栏右边的一个图标变为彩色,去谷歌商店自行下载Postman,就可以开始你的OneNet平台数据数据测试之旅啦!~



谷歌访问助手2.2.2.rar (240.42 KB, 下载次数: 3231)
回复

举报

2

主题

13

帖子

43

积分

新手上路

Rank: 1

积分
43
发表于 2019-3-6 13:37:49 | 显示全部楼层
  1. {
  2.     "errno": 0,
  3.     "data": {
  4.         "count": 1,
  5.         "datastreams": [
  6.             {
  7.                 "datapoints": [
  8.                     {
  9.                         "at": "2019-02-23 00:56:43.000",
  10.                         "value": 11
  11.                     }
  12.                 ],
  13.                 "id": "temperature"
  14.             }
  15.         ]
  16.     },
  17.     "error": "succ"
  18. }
复制代码

2

主题

13

帖子

43

积分

新手上路

Rank: 1

积分
43
发表于 2019-3-6 13:37:08 | 显示全部楼层
请问如果返回的count一直为1要怎么办呀C:\Users\Administrator\Desktop\QQ截图postman.png
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表