1、API介绍
使用onenet平台提供的设备命令API,直接向设备下发指令,当设备收到指令并进行应答时,API返回设备应答内容
请求API:POST
/v1/synccmds?device_id=866760442&timeout=30
请求体body中携带:用户自定义命令数据内容
device_id
:设备idtimeout
:同步API最长等待时间,取值范围 5-30, 单位秒
访问接口得到的返回语法:
Content-type: application/json{"errno": 0,"error": "success","data": {"cmd_uuid": "3b6ab6e6-f729-4825-83e6-397d8c27c284","cmd_resp": "cmVjZWl2ZSBjbWQuLi4="}}
返回参数:
errno
:错误码error
: 错误描述cmd_uuid
: 命令IDcmd_resp
:设备应答内容,base64编码格式
返回错误码
返回错误示例
{"errno": 15,"error": "sync cmd timeout"}
使用限制
命令请求body
数据长度必须小于1k设备应答时payload
长度必须小于1k
2、新建访问URL工具类
package com.wzkj.utils;import com.alibaba.fastjson.JSONObject;import mons.httpclient.HttpClient;import mons.httpclient.methods.PostMethod;import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Iterator;import java.util.Map;/*** HTTP工具** @author hyh*/public class HttpUtils {/*** 发送数据到POST请求路径** @param url请求路径* @param headers 请求头* @param params 请求参数* @return String*/@SuppressWarnings("unchecked")public static String SendPost(String url, JSONObject headers, JSONObject params) {String ret = "";HttpClient client = new HttpClient();PostMethod method = new PostMethod(url);for (Map.Entry<String, Object> entry : headers.entrySet()) {String key = entry.getKey();method.addRequestHeader(key, headers.getString(key));}for (Map.Entry<String, Object> entry : params.entrySet()) {String key = entry.getKey();method.addParameter(key, params.getString(key));}try {client.executeMethod(method);BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));StringBuffer stringBuffer = new StringBuffer();String str = "";while ((str = reader.readLine()) != null) {stringBuffer.append(str);}ret = stringBuffer.toString();} catch (Exception e) {e.printStackTrace();} finally {method.releaseConnection();}return ret;}/*** 发送数据到POST请求** @param url发送设备命令的http地址* @param headers 请求头* @param params 请求参数* @return String 返回结果*/@SuppressWarnings({"unchecked", "deprecation"})public static String SendPost(String url, net.sf.json.JSONObject headers, String params) {String ret = "";HttpClient client = new HttpClient();PostMethod method = new PostMethod(url);Iterator<String> header = headers.keys();while (header.hasNext()) {String key = header.next();method.addRequestHeader(key, headers.getString(key));}method.setRequestBody(params);try {client.executeMethod(method);BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));StringBuffer stringBuffer = new StringBuffer();String str = "";while ((str = reader.readLine()) != null) {stringBuffer.append(str);}ret = stringBuffer.toString();} catch (Exception e) {e.printStackTrace();} finally {method.releaseConnection();}return ret;}}
3、生成访问授权方法
该方法在demo中就有,Token类就是生成授权的类,而在onenet中,token有两种,一种是API访问的token,一种是设备连接的token。
在其main方法中有个参数resourceName
,其不同的设计格式可以生成不同的访问token
当前场景是使用API访问,所以resourceName
的格式为products/{pid}
我的产品ID是480701
,accessKey
是ZQjnxxt0B5Rrdn17Kzz11+UOM3UhJePYMYEgkHtXpV4=
,代码如下:productId
和accessKey
参数改成自己的即可
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {// oneNet的产品IDString productId = "480701";// 产品的access_keyString accessKey = "ZQjnxxt0B5Rrdn17Kzz11+UOM3UhJePYMYEgkHtXpV4=";// 版本号,无需修改String version = "-10-31";// API访问 访问资源String resourceName = "products/" + productId;// 访问过期时间String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";//签名方法,支持md5、sha1、sha256String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);System.out.println("Authorization: " + token);}
运行后生成的token是:version=-10-31&res=products%2F480701&et=1653707690&method=sha1&sign=JahknKD6%2FXuvbPVA3fIj3A%2FoTiA%3D
4、访问API
HttpUtils提供了两种访问URL方式:
方式1:请求头使用com.alibaba.fastjson.JSONObject
,请求体为JSON格式
@Testpublic void dispatchOrders(){String deviceId = "866760442";String token = "version=-10-31&res=products%2F480701&et=1712112818&method=sha1&sign=89dqMv4ygwfq5dUZXEHsv88m%2BGI%3D";JSONObject headers = new JSONObject();headers.put("Authorization", token);JSONObject jsonObject = new JSONObject();// 发送给设备的命令参数jsonObject.put("color", "-101");String url = "/v1/synccmds?device_id=" + deviceId + "&timeout=30";System.out.println(jsonObject);String sendPost = HttpUtils.SendPost(url, headers, jsonObject);System.out.println(sendPost);}
方式二:请求头使用net.sf.json.JSONObject
,请求体为String格式
@Testpublic void dispatchOrders2(){net.sf.json.JSONObject headers = new net.sf.json.JSONObject();String token = "version=-10-31&res=products%2F480701&et=1712112818&method=sha1&sign=89dqMv4ygwfq5dUZXEHsv88m%2BGI%3D";headers.put("Authorization", token);String deviceId = "724860362";// 发送给设备的命令参数String param = "0";String params = String.format("\"S1:%s\"", param);String url = "/v1/synccmds?device_id=" + deviceId + "&timeout=30";String sendPost = HttpUtils.SendPost(url, headers, params);System.out.println(sendPost);}
运行后的返回结果:
设备应答内容为cmVjZWl2ZSBjbWQuLi4=
,base64编码格式,将其解密为:receive cmd...
,翻译过来就是收到命令
5、解析请求结果
添加Base64解析工具类:
package com.yuyun.utils;import sun.misc.BASE64Decoder;import java.io.IOException;/*** Base64工具类** @author hyh*/public class Base64Utils {/*** Base64解码** @param bytes Base64加密的字节码* @return String* @throws IOException IOException*/public static String Base64Decode(byte[] bytes)throws IOException {BASE64Decoder base64decoder = new BASE64Decoder();byte[] bs = base64decoder.decodeBuffer(new String(bytes));return new String(bs, "UTF-8");}}
解析sendPost:
JSONObject sp = JSONObject.parseObject(sendPost);int errno = sp.containsKey("errno") ? sp.getInteger("errno") : -1;String error = sp.containsKey("error") ? sp.getString("error") : "";if (errno != 0 && StringUtils.isNotBlank(error)) {System.out.println(error);}JSONObject data = sp.containsKey("data") ? sp.getJSONObject("data") : new JSONObject();if (data.containsKey("cmd_resp")) {String cmdResp = data.getString("cmd_resp");try {String str = Base64Utils.Base64Decode(cmdResp.getBytes());System.out.println("解码后的cmd_resp:" + str);} catch (Exception e) {System.out.println("解码失败!");}}
输出结果:
完整代码
@Testpublic void dispatchOrders() {String deviceId = "866760442";String token = "version=-10-31&res=products%2F480701&et=1712112818&method=sha1&sign=89dqMv4ygwfq5dUZXEHsv88m%2BGI%3D";JSONObject headers = new JSONObject();headers.put("Authorization", token);JSONObject jsonObject = new JSONObject();// 发送给设备的命令参数jsonObject.put("color", "-101");String url = "/v1/synccmds?device_id=" + deviceId + "&timeout=30";System.out.println(jsonObject);String sendPost = HttpUtils.SendPost(url, headers, jsonObject);System.out.println(sendPost);JSONObject sp = JSONObject.parseObject(sendPost);int errno = sp.containsKey("errno") ? sp.getInteger("errno") : -1;System.out.println("errno:" + errno);String error = sp.containsKey("error") ? sp.getString("error") : "";System.out.println("error:" + error);if (errno != 0 && StringUtils.isNotBlank(error)) {System.out.println(error);}JSONObject data = sp.containsKey("data") ? sp.getJSONObject("data") : new JSONObject();System.out.println(data);if (data.containsKey("cmd_resp")) {String cmdResp = data.getString("cmd_resp");try {String str = Base64Utils.Base64Decode(cmdResp.getBytes());System.out.println("解码后的cmd_resp:" + str);} catch (Exception e) {System.out.println("解码失败!");}}}
demo地址:/hyh17808770899/spring-boot/tree/master/springboot-onenet