1 前面的话

在onenet的 onenet studio 服务001里面我们已经讲过了使用postman调用onenet官方的API。
但是请求的URL是有问题的,并不是官方给的一个标准的请求方式。

这里我们一获得设备的详细信息为例子,

2 获取设备最新信息API(瞎猫版)

这种方式就是瞎猫碰到死耗子

2.1 在onenet平台里面调试API

image.png
进到品台的运维监控—API调试——应用开发类,就会发现里面有连个接口,一个是获取设备属性,一个是设备属性最新数据查询。 前者需要设备在线,后者设备属性最新数
据查询,这个不需要设备在线,可以获得设备里面的最后一条数据,但是这个数据包含设备里面所有的数据流。

我们这里就以设备属性最先数据查询。为例,因为这个API不需要设备在线。

品台里面调试开始,配置好设备的,产品名,产品id,设备名,之后我们点击执行,可以看到已经得到了服务器返回来的设备数据了。
image.png
我们看看平台发送的http请求的数据,这个是一个get方式的请求,我们可以打开postman,将url和请求头,以及鉴权信息写进去,应该也可以得到设备的数据。

  1. {
  2. "url": "https://open.iot.10086.cn/studio/debug/api/application?version=1&action=QueryDeviceProperty&project_id=ZIVS7i&product_id=FkWRPqXmGF&device_name=CWBW_02",
  3. "method": "get",
  4. "header": {
  5. "Accept": "application/json, text/plain, */*",
  6. "authorization": "version=2020-05-29&res=userid%2F274573&et=1682055413&method=sha1&sign=LA7NJFNiZBBwsJvQtkWLgdoHwhU%3D"
  7. },
  8. "query": {
  9. "version": 1,
  10. "action": "QueryDeviceProperty",
  11. "project_id": "ZIVS7i",
  12. "product_id": "FkWRPqXmGF",
  13. "device_name": "CWBW_02"
  14. }
  15. }

2.2 postman调用平台API

image.png

我们可以看到借助平台里面的API调试,我们确实可以得到 平台的设备数据

但是但是但是,这种方式完全就是瞎猫碰到死耗子。

3 获取设备最新数据API(文档版)

在2里面我们确实可以借助平台调试,然后赋值平台调试的时候的请求参数 ,得到设备的最新数据,但是上面的方式就是瞎猫碰到死耗子

这里我们根据onenet平台提供的API文档来看看标准的请求方式是怎么实现的。
这里我们用的onenet的服务是 onenet studio服务,我们就去查看onenet studio的开发文档,文档地址
https://open.iot.10086.cn/doc/v5/develop/detail/634
进到文档里面

  • 应用开发 — 应用API ——使用说明 先看一下API的使用规则

image.png
可以看到 里面有一个 namespace字段和action字段是需要我们自己根据调用的方法自己写的。我们使用的是应用开发类里面的 设备最新数据获取,所以namespace这个字段就写 application
https://openapi.heclouds.com/application?action=xxxx&version=1

  • 然后我们进到 应用开发 — 应用开发类 —- 应用API。

image.png
可以看到设备最新数据查询这个方法,的接口名是 QueryDeviceProperty ,请求方法是get那么这个链接
https://openapi.heclouds.com/application?action=xxxx&version=1
可以变为
https://openapi.heclouds.com/application?action=QueryDeviceProperty&version=1
但是这个时候可以看到 设备属性最新数据要求了几个参数,project_id(项目id),product_id(产品id),device_name(设备名)
这三个参数,我们要在url里面穿入这三个参数,所以右边为了
https://openapi.heclouds.com/application?action=QueryDeviceProperty&version=1&project_id=ZIVS7i&product_id=FkWRPqXmGF&device_name=CWBW_02
这样请求的url就好了。

  • 然后我们吧这个链接放到postman里面进行调试,看到他报错说我们鉴权失败了

image.png

下面我们就开始解决鉴权失败的问题

  • 通过查看文档 应用开发——应用API—-安全鉴权

image.png
image.png
找一下四个参数:

——————————————————————————————-
version = 2020-05-29
res = userid/274573
et = 1653116504 时间按不需要我们自己转换了,java代码里面会将我们当前时间往后40天
image.png
method = sha1
accessKey=
HUsjVYRsu6qnGyd+FUGVPM9QDTZ/n+5sttdpSA+IcYU3QNtaxKdS96XY97sWjSlNdcIZFUHuSL9+DGvdQif5rA==
————————————————————————————————————-

然后呢他们有给了一个java生成签名结果的字符串,
java方法,我们使用这方法,放到idea里面,设置上面的5个 参数,就可以使用 签名结果了

  1. import javax.crypto.Mac;
  2. import javax.crypto.spec.SecretKeySpec;
  3. import java.io.UnsupportedEncodingException;
  4. import java.net.URLEncoder;
  5. import java.security.InvalidKeyException;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.util.Base64;
  8. public class productSING {
  9. public static String assembleToken(String version, String resourceName, String expirationTime, String signatureMethod, String accessKey)
  10. throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
  11. StringBuilder sb = new StringBuilder();
  12. String res = URLEncoder.encode(resourceName, "UTF-8");
  13. String sig = URLEncoder.encode(generatorSignature(version, resourceName, expirationTime, accessKey, signatureMethod), "UTF-8");
  14. sb.append("version=")
  15. .append(version)
  16. .append("&res=")
  17. .append(res)
  18. .append("&et=")
  19. .append(expirationTime)
  20. .append("&method=")
  21. .append(signatureMethod)
  22. .append("&sign=")
  23. .append(sig);
  24. return sb.toString();
  25. }
  26. public static String generatorSignature(String version, String resourceName, String expirationTime, String accessKey, String signatureMethod)
  27. throws NoSuchAlgorithmException, InvalidKeyException {
  28. String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version;
  29. String signature;
  30. byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod);
  31. signature = Base64.getEncoder().encodeToString(bytes);
  32. return signature;
  33. }
  34. public static byte[] HmacEncrypt(String data, String key, String signatureMethod)
  35. throws NoSuchAlgorithmException, InvalidKeyException {
  36. //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
  37. SecretKeySpec signinKey = null;
  38. signinKey = new SecretKeySpec(Base64.getDecoder().decode(key),
  39. "Hmac" + signatureMethod.toUpperCase());
  40. //生成一个指定 Mac 算法 的 Mac 对象
  41. Mac mac = null;
  42. mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase());
  43. //用给定密钥初始化 Mac 对象
  44. mac.init(signinKey);
  45. //完成 Mac 操作
  46. return mac.doFinal(data.getBytes());
  47. }
  48. public enum SignatureMethod {
  49. SHA1, MD5, SHA256;
  50. }
  51. public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
  52. String version = "2020-05-29";
  53. String resourceName = "userid/274573";
  54. String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";
  55. String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
  56. String accessKey = "HUsjVYRsu6qnGyd+FUGVPM9QDTZ/n+5sttdpSA+IcYU3QNtaxKdS96XY97sWjSlNdcIZFUHuSL9+DGvdQif5rA==";
  57. String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
  58. System.out.println("Authorization:" + token);
  59. }
  60. }

image.png

可以看到他生成的一个鉴权用的签名字符串。
现在鉴权信息也有了 ,我们回到postman里面,点击Authorization,选择API key
image.png

好了到目前位置我们已经可以 使用平台给的 API 使用标准的方法 拿到平台返回来的数据了。

4 设备属性设置(失败)

模拟2.2 里面的方式,通过读取文档 应用开发—-应用开发类——设备属性设置
我们可以在postman里面发送请求
当设备不在线时候报错:设备不在线
image.png
当设备在线的时候又报错: 设备没有订阅
image.png

5 设备属性上报

4 里面的设备属性设置API我上传数据的时候失败了,我有看到了文档里面有另外一个API

5.1 先看使用API使用说明

image.png
从图片里面可以看到 使用说明,发送的是post请求,而且 url, 请求头,请求体里面都需要我们设置一些参数
我们先把这个格式打出来
POST https://${Address}/${url}?${url参数}
Header参数:token,Content-Type
请求体Body:OneJson 其实就是json格式的数据

目前已经这知道
Address是 https://open.iot.10086.cn/studio/http
url是 /device/thing/property/post
修改格式
POST https://open.iot.10086.cn/studio/http/device/thing/property/post?${url参数}
Header参数:token,Content-Type
请求体Body:OneJson 其实就是json格式的数据

url参数里面有连个参数,一个是topic 一个是 Protocol 我们就开始找这连个参数
image.png
可以看到 设备属性上报topic是 $sys/{pid}/{device-name}/thing/property/post
我们将自己的pid 产品id ,device-name 设备名填写进去 ,
topic就是 $sys/FkWRPqXmGF/CWBW_02/thing/property/post

Protocol给了三个值,我们这里使用的是MQTT我也不知道为什么要用这个,不然回报错 协议不匹配
修改请求的模板
POST https://open.iot.10086.cn/studio/http/device/thing/property/post?topic=$sys/FkWRPqXmGF/CWBW_02/thing/property/post&protocol=mqtt
Header参数:token,Content-Type
请求体Body:OneJson 其实就是json格式的数据

5.2 设置token和content-type

  • url里面的参数我们已经看完了,现在开始设置请求头里面的参数

可以看到请求头里面有两个参数,一个是 token ,一个是 Content-type
image.png
我们点进去这个链接里面有生成token的方法,和工具生成token的方法和工具
我们打开工具
image.png
et就是unix时间,在线的unix事件转换工具unix时间在线转换工具这个时间一定要是未来的时间,不然就会被拒绝访问。
image.png
这里我使用的et是 : 1653116504
打开token生成工具
image.png
可以看到我们还缺少key这个参数,我们在看看文档
image.png
这个key就是秘钥,产品级,设备级都可以,
说的在具体一点:产品级的key叫产品key,设备级的key叫做设备秘钥 ,这两个值都是可以的,
以我的产品为例
产品key是 :QvgnqE1kZBomEJmZsX6geOrQmZdBJd5DJK5EremSI7Y=
生成的token是:version=2018-10-31&res=products%2FFkWRPqXmGF%2Fdevices%2FCWBW_02&et=1653116504&method=md5&sign=rehMS%2Foqkvo%2FRHzElv%2BzOQ%3D%3D

设备key是:P6oyCh/SOmR8727I6DeDpxMZgn4mnGs6zvx5d6Yt218=
生成的token是:version=2018-10-31&res=products%2FFkWRPqXmGF%2Fdevices%2FCWBW_02&et=1653116504&method=md5&sign=S7MkTpcqNXO47heUFoR%2Fbw%3D%3D

这里我先使用产品key的token
好了这个时候我们来修改请求参数
POST https://open.iot.10086.cn/studio/http/device/thing/property/post?topic=$sys/FkWRPqXmGF/CWBW_02/thing/property/post&protocol=mqtt
Header参数:token=version=2018-10-31&res=products%2FFkWRPqXmGF%2Fdevices%2FCWBW_02&et=1653116504&method=md5&sign=rehMS%2Foqkvo%2FRHzElv%2BzOQ%3D%3D,
Content-Type=application/json
请求体Body:OneJson 其实就是json格式的数据

最后就出一个请求体的格式了

5.3 请求体的参数

到文档里面—-设备接入与管理——http协议接入—-直连设备设备属性上报
文档里面给了个请求体的数据格式
image.png
我们来写一个json格式的请求体数据,想我的设备的Alerm这个数据点里面传递一个1

  1. {
  2. "id": "123",
  3. "version": "1.0",
  4. "params": {
  5. "Alerm": {
  6. "value": 1
  7. }
  8. }
  9. }

5.4 最终的请求数据

注意我们的请求参数是post

  • 设置请求url

image.png

  • 设置请请求头

请求头里面的鉴权信息
image.png
设置请求头里面的content-Type
image.png

  • 设置请求体数据,发送请求

image.png
可以看到数据已近发送过去了,我们到设备里面看一下,数据已经过来了

image.png