赞
踩
使用onenet平台提供的设备命令API,直接向设备下发指令,当设备收到指令并进行应答时,API返回设备应答内容
请求API:POST
http://api.heclouds.com/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编码格式返回错误码
错误码 | 错误描述 | 说明 |
---|---|---|
12 | device not found | 设备不存在 |
13 | device not online | 设备不在线 |
15 | sync cmd timeout | 设备命令应答超时 |
返回错误示例
{
"errno": 15,
"error": "sync cmd timeout"
}
使用限制
body
数据长度必须 小于1kpayload
长度必须 小于1kpackage com.wzkj.utils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.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;
}
}
该方法在demo中就有,Token类就是生成授权的类,而在onenet中,token有两种,一种是API访问的token,一种是设备连接的token。
在其main方法中有个参数resourceName
,其不同的设计格式可以生成不同的访问token
场景 | res参数格式 | 示例 | 说明 |
---|---|---|---|
API访问 | products/{pid} | products/123123 | |
设备连接 | products/{pid}/devices/{device_name} | products/123123/devices/mydev | 需使用设备级密钥 |
当前场景是使用API访问,所以resourceName
的格式为products/{pid}
我的产品ID是480701
,accessKey
是ZQjnxxt0B5Rrdn17Kzz11+UOM3UhJePYMYEgkHtXpV4=
,代码如下:productId
和accessKey
参数改成自己的即可
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
// oneNet的产品ID
String productId = "480701";
// 产品的access_key
String accessKey = "ZQjnxxt0B5Rrdn17Kzz11+UOM3UhJePYMYEgkHtXpV4=";
// 版本号,无需修改
String version = "2018-10-31";
// API访问 访问资源
String resourceName = "products/" + productId;
// 访问过期时间
String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";
//签名方法,支持md5、sha1、sha256
String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
System.out.println("Authorization: " + token);
}
运行后生成的token是:version=2018-10-31&res=products%2F480701&et=1653707690&method=sha1&sign=JahknKD6%2FXuvbPVA3fIj3A%2FoTiA%3D
HttpUtils提供了两种访问URL方式:
方式1:请求头使用com.alibaba.fastjson.JSONObject
,请求体为JSON格式
@Test
public void dispatchOrders(){
String deviceId = "866760442";
String token = "version=2018-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 = "http://api.heclouds.com/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格式
@Test
public void dispatchOrders2(){
net.sf.json.JSONObject headers = new net.sf.json.JSONObject();
String token = "version=2018-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 = "http://api.heclouds.com/v1/synccmds?device_id=" + deviceId + "&timeout=30";
String sendPost = HttpUtils.SendPost(url, headers, params);
System.out.println(sendPost);
}
运行后的返回结果:
设备应答内容为cmVjZWl2ZSBjbWQuLi4=
,base64编码格式,将其解密为:receive cmd...
,翻译过来就是收到命令
添加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("解码失败!");
}
}
输出结果:
完整代码
@Test
public void dispatchOrders() {
String deviceId = "866760442";
String token = "version=2018-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 = "http://api.heclouds.com/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地址:https://gitee.com/hyh17808770899/spring-boot/tree/master/springboot-onenet
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。