前面我们简单熟悉了HTTP协议,也知道如何利用Fiddler来学习中移动物联网平台的POST功能。一个真正实用的应用,可能需要客户端向服务器提交数据,也可能需要从服务器获取数据,这样客户端和服务器之间的通信才是双向的,即可以采集数据,也可以控制设备。
下面我们就利用Fiddler来帮助我们学习如何从服务器GET数据,我们还是以数据点为例。
打开OneNet API中有关GET数据点的页面,我们来看看API是如何规定的。
请求的方法是GET,URL跟POST中一样,也是http://api.heclouds.com/devices/[device_id]/datapoints, 同样也需要添加api key来验证身份,可以用项目的key,也可以用设备的key,都可以。
其实这个时候已经满足服务器端的要求了,按Execute,便会哗啦啦的下载该设备下面所有数据流的数据,不一定都是我们需要的,因此我们要设置请求参数,来过滤掉一些。
重新回到API手册,看看请求参数是如何要求的。
参数分两种,一种是可选的公共参数,一种是必选的模式参数。
公共参数
可以按数据流名称来过滤,不设置的话,就是返回所有数据流的数据点;可以设置多个数据流,名称中间用逗号分隔开就可以。
可以设置起止日期/时间来返回指定时间范围内的数据,但是区间不能超过一年。
我们试试指定某个数据流,看看那个下面都有些啥:
- GET http://api.heclouds.com/devices/*****/datapoints?datastream_id=temperature HTTP/1.1
- User-Agent: Fiddler
- Host: api.heclouds.com
- api-key: 0kGf*******UG1h4*****jTgA
复制代码
注意第一个参数前面要用?分隔,后面各个参数之间用&连接。
运行之后,服务器返回最新值:
- HTTP/1.1 200 OK
- Date: Tue, 13 Oct 2015 05:40:00 GMT
- Content-Type: application/json
- Content-Length: 141
- Connection: keep-alive
- Server: Apache-Coyote/1.1
- Pragma: no-cache
- {**"errno":0**,"data":{**"count":1**,"datastreams":[{"datapoints":[{"at":"2015-10-12 00:35:43.000","value":42}],"id":"temperature"}]},"error":"succ"}
复制代码
从上面返回的数据点可以看出,如果不指定起止时间,服务器只返回最新值,我们试试指定起始时间:
复制代码
服务器返回了100条数据,而所有符合条件的数据超过了100条,
- {"errno":0,"data":{"cursor":"20967_69131_1430236470234","count":100,"datastreams":[{"datapoints":[{"at":"2014-09-01 15:11:01.000","value":15},...}
复制代码
我们可以指定其他参数来获取指定数量的数据,这个就需要设置模式参数。
模式参数
模式参数是必选的,四个中选择一个,API手册中是这么规定的:
- (1)最新数据点获取
- 只指定数据流参数或者不指定任何参数则进入此模式。返回每个数据流最新的1个数据点。
- (2)历史数据点获取
- 只指定时间范围,则进入此模式。支持数据流参数,同时支持以下可选参数:
- 1.limit:返回结果中数据点最大数量,默认100,最大6000,
- 2.cursor:查询条件返回结果超过limit条数时,用于遍历的游标。
- (3)数据点采样
- 指定interval参数和时间范围进入此模式。Interval参数指定采样间隔时间,单位秒,最小15秒,最大1天。支持以下可选参数:
- 1.limit:返回结果中数据点最大数量,默认100,最大6000,
- 2.cursor:查询条件返回结果超过limit条数时,用于遍历的游标。
- (4)数据点统计计算
- 指定method参数和时间范围进入此模式。method参数指定计算方法,可选的值为sum/avg/min/max,
- 分别表示求和/均值/最小值/最大值,只支持值为数值类型的数据点。支持以下可选参数:
- 1.limit:参与运算的数据点最大数量,默认6000,最大6000,
- 2.first:返回结果中最值的时间点,1表示最早的时间,0表示最近的时间,默认为1。
- 第2、3、4模式均须指定时间范围。
复制代码
这个有点意思,既然是必须的,但又可以什么也不用设置
前面的实验知道,如果仅仅指定时间范围,那么默认只返回100条数据,如果需要获取超过100条,那就得使用limit参数 请求行改为:
- GET /devices/*****/datapoints?datastream_id=temperature&start=2014-05-12T17:22:33&limit=120 HTTP/1.1
复制代码
服务器就会把120条符合条件的数据返回给客户端:
- HTTP/1.1 200 OK
- Date: Tue, 13 Oct 2015 06:43:49 GMT
- Content-Type: application/json
- Content-Length: 5422
- Connection: keep-alive
- Server: Apache-Coyote/1.1
- Pragma: no-cache
- {"errno":0,"data":{"cursor":"*****_*****_1430236679432","count":120,"datastreams":[{"datapoints":[{"at":"2014-09-01 15:11:01.000","value":15},...}
复制代码
至于这个cursor是干嘛的,文档中没有详细说明。
我们再来看看interval参数,它得和时间范围参数一起使用。我们先不用它,取5个数据点,然后启用interval参数,也是5个点,对比看有什么区别。
先来不使用interval参数的5个点:
- GET /devices/*****/datapoints?datastream_id=temperature&start=2014-05-12T17:22:33&limit=5 HTTP/1.1
复制代码
结果:
- {
- "errno":0,
- "data":{
- "cursor":"*****_*****_1427703150000",
- "count":5,
- "datastreams":[
- {
- "datapoints":[
- {
- "at":"2014-09-01 15:11:01.000",
- "value":15
- },
- {
- "at":"2014-09-01 15:16:01.000",
- "value":20
- },
- {
- "at":"2015-03-01 15:11:01.000",
- "value":115
- },
- {
- "at":"2015-03-01 15:16:01.000",
- "value":120
- },
- {
- "at":"2015-03-21 16:12:21.000",
- "value":130
- }
- ],
- "id":"temperature"
- }
- ]
- },
- "error":"succ"
- }
复制代码
再来5个带interval参数的,interval取值为30分钟=60*30=1800:
- GET /devices/*****/datapoints?datastream_id=temperature&start=2014-05-12T17:22:33&limit=5&interval=1800 HTTP/1.1
复制代码
结果:
- {
- "errno":0,
- "data":{
- "cursor":"20967_69131_1428736589000",
- "count":6,
- "datastreams":[
- {
- "datapoints":[
- {
- "at":"2014-09-01 15:11:01.000",
- "value":15
- },
- {
- "at":"2015-03-01 15:11:01.000",
- "value":115
- },
- {
- "at":"2015-03-21 16:12:21.000",
- "value":130
- },
- {
- "at":"2015-03-30 16:12:30.000",
- "value":130
- },
- {
- "at":"2015-04-05 15:11:05.000",
- "value":115
- },
- {
- "at":"2015-04-10 15:11:05.000",
- "value":15
- }
- ],
- "id":"temperature"
- }
- ]
- },
- "error":"succ"
- }
复制代码
经过对比第1/2个数据,我们就能发现差别。不带interval参数时,第1个数据点和第二个数据点的服务器接收时间相差5分钟;我们设置的interval为30分钟,那么第2个数据显然应该被过滤掉,事实上的确如此。因此带interval参数之后,服务器按照指定时间间隔跳着选取的。
最后那个计算的参数,可能是我用错了,总是没得到正确的值,希望平台技术支持人员能够指正。我在上面那个GET请求后面直接加上&method=sum,如果带interval参数,那么照样取到的是6条数据,如果不带interval参数,则提示13号错误:data too large,其实那几个数还真不大。 请求:GET /devices/*****/datapoints?datastream_id=temperature&start=2014-05-12T17:22:33&limit=2&method=sum HTTP/1.1
即使是method选择min,也是同样错误。
|