package com.hdl.sdk.link.gateway;
|
|
|
import com.google.gson.JsonArray;
|
import com.google.gson.JsonObject;
|
import com.google.gson.reflect.TypeToken;
|
import com.hdl.sdk.link.common.config.TopicConstant;
|
import com.hdl.sdk.link.common.event.EventDispatcher;
|
import com.hdl.sdk.link.common.event.EventListener;
|
import com.hdl.sdk.link.common.exception.HDLLinkCode;
|
import com.hdl.sdk.link.common.exception.HDLLinkException;
|
import com.hdl.sdk.link.common.utils.IdUtils;
|
import com.hdl.sdk.link.common.utils.IpUtils;
|
import com.hdl.sdk.link.common.utils.TextUtils;
|
import com.hdl.sdk.link.common.utils.ThreadToolUtils;
|
import com.hdl.sdk.link.common.utils.gson.GsonConvert;
|
|
import com.hdl.sdk.link.core.bean.LinkRequest;
|
import com.hdl.sdk.link.core.bean.LinkResponse;
|
import com.hdl.sdk.link.core.bean.gateway.GatewayBean;
|
import com.hdl.sdk.link.core.bean.response.BaseLocalResponse;
|
import com.hdl.sdk.link.core.callback.GatewayCallBack;
|
import com.hdl.sdk.link.core.callback.HDLLinkCallBack;
|
import com.hdl.sdk.link.core.connect.HDLConnectHelper;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* Created by hxb on 2021/12/23.
|
*/
|
public class HDLLinkLocalGateway {
|
//instance
|
private volatile static HDLLinkLocalGateway instance;
|
|
//getInstance
|
public static synchronized HDLLinkLocalGateway getInstance() {
|
if (instance == null) {
|
synchronized (HDLLinkLocalGateway.class) {
|
if (instance == null) {
|
instance = new HDLLinkLocalGateway();
|
}
|
}
|
}
|
return instance;
|
}
|
|
/**
|
* 网关列表,记录所有搜索到的网关,可能包含断线的网关
|
*/
|
private final List<GatewayBean> gatewayBeanList = new ArrayList();
|
|
/**
|
* 获取缓存的网关列表,可能包含断线的网关
|
*
|
* @return 网关列表
|
*/
|
public List<GatewayBean> getGatewayList() {
|
return gatewayBeanList;
|
}
|
|
/**
|
* 通过oid或者网关ID或者AMC获取内存中的网关
|
*
|
* @param oidOrGatewayId
|
* @return
|
*/
|
public GatewayBean getGatewayByOidOrGatewayId(String oidOrGatewayId) {
|
if (TextUtils.isEmpty(oidOrGatewayId)) {
|
return null;
|
}
|
for (GatewayBean gatewayBean : gatewayBeanList) {
|
if (oidOrGatewayId.equals(gatewayBean.getOid())
|
|| oidOrGatewayId.equals(gatewayBean.getGatewayId())
|
|| oidOrGatewayId.equals(gatewayBean.getDevice_mac())
|
|| oidOrGatewayId.equals(gatewayBean.getIp_address())
|
)
|
return gatewayBean;
|
}
|
return null;
|
}
|
|
/**
|
* 通过IP获取网关信息
|
*
|
* @param ipAddress
|
* @return
|
*/
|
public GatewayBean getGatewayByIpAddress(String ipAddress) {
|
if (TextUtils.isEmpty(ipAddress)) {
|
return null;
|
}
|
for (GatewayBean gatewayBean : gatewayBeanList) {
|
if (ipAddress.equals(gatewayBean.getIp_address()))
|
return gatewayBean;
|
}
|
return null;
|
}
|
|
/**
|
* 搜索网关,只发一次,没有回调
|
*/
|
public void serchGatewayOneTime() {
|
String time = String.valueOf(System.currentTimeMillis());
|
JsonObject jsonObject = new JsonObject();
|
jsonObject.addProperty("id", IdUtils.getUUId());
|
jsonObject.addProperty("time_stamp", time);
|
LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH,
|
jsonObject.toString(), false);
|
|
String ipAddress = IpUtils.getBroadcastAddress();
|
new HDLConnectHelper(1, ipAddress, message, false).send();
|
}
|
|
/**
|
* 创新所有在线的网关,包括当前住宅的及没有绑定过的网关
|
*
|
* @param callBack 回调
|
*/
|
public void refreshGatewayByHome(String homeId, GatewayCallBack callBack) {
|
refreshGatewayByHome(homeId,callBack,false);
|
}
|
|
/**
|
* 创新所有在线的网关,包括当前住宅的及没有绑定过的网关
|
*
|
* @param callBack 回调
|
*/
|
public void refreshGatewayByHome(String homeId, GatewayCallBack callBack,boolean needOldGateway) {
|
|
String topicReply = TopicConstant.GATEWAY_SEARCH_REPLY;
|
final List<GatewayBean> tempGatewayBeanList = new ArrayList<>();
|
EventListener eventListener = getSearchGatewayEvent(homeId, tempGatewayBeanList);
|
EventDispatcher.getInstance().register(topicReply, eventListener);
|
|
ThreadToolUtils.getInstance().newFixedThreadPool(1).execute(new Runnable() {
|
@Override
|
public void run() {
|
int count = 5;
|
while (0 < count--) {
|
try {
|
//搜索网关
|
serchGatewayOneTime();
|
Thread.sleep(300L);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
}
|
//超出次数后移除监听事件
|
EventDispatcher.getInstance().remove(topicReply, eventListener);
|
if (callBack != null) {
|
if (tempGatewayBeanList.size() == 0 && needOldGateway) {
|
for (int i = 0; i < gatewayBeanList.size(); i++) {
|
if (homeId.equals(gatewayBeanList.get(i).getHomeId())) {
|
tempGatewayBeanList.add(gatewayBeanList.get(i));
|
}
|
}
|
}
|
if (tempGatewayBeanList.size() == 0) {
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GET_GATEWAY_FAILURE_ERROR));
|
} else {
|
callBack.onSuccess(tempGatewayBeanList);
|
}
|
}
|
}
|
});
|
}
|
|
/**
|
* 创新所有在线的网关,包括当前住宅的及没有绑定过的网关
|
*
|
* @param callBack 回调
|
*/
|
public void refreshGateway(GatewayCallBack callBack) {
|
|
String topicReply = TopicConstant.GATEWAY_SEARCH_REPLY;
|
final List<GatewayBean> tempGatewayBeanList = new ArrayList<>();
|
EventListener eventListener = getSearchGatewayEvent(tempGatewayBeanList);
|
EventDispatcher.getInstance().register(topicReply, eventListener);
|
|
ThreadToolUtils.getInstance().newFixedThreadPool(1).execute(new Runnable() {
|
@Override
|
public void run() {
|
int count = 5;
|
while (0 < count--) {
|
try {
|
//搜索网关
|
serchGatewayOneTime();
|
Thread.sleep(300L);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
}
|
|
|
//超出次数后移除监听事件
|
EventDispatcher.getInstance().remove(topicReply, eventListener);
|
if (callBack != null) {
|
if (tempGatewayBeanList.size() == 0) {
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GET_GATEWAY_FAILURE_ERROR));
|
} else {
|
|
callBack.onSuccess(tempGatewayBeanList);
|
}
|
}
|
}
|
});
|
}
|
|
/**
|
* 获取搜索网关事件
|
*
|
* @param homeId
|
* @return
|
*/
|
private EventListener getSearchGatewayEvent(String homeId, final List<GatewayBean> tempGatewayBeanList) {
|
//注册搜索网关监听
|
return new EventListener() {
|
@Override
|
public void onMessage(Object msg) {
|
if (!(msg instanceof LinkResponse)) {
|
return;
|
}
|
GatewayBean gateway = getGatewayBeanByResponse((LinkResponse) msg);
|
if (gateway == null) {
|
return;
|
}
|
gateway.setOnline(true);
|
gateway.setIsLocalGateWay(true);//本地搜索到的网关标识为本地网关
|
//只加载住宅一样的或者网关还没有配置过的
|
if (homeId.equals(gateway.getHomeId()) || TextUtils.isEmpty(gateway.getHomeId())) {
|
//更新缓存网关,会记录所有收到的网关,以为了保存网关的IP信息
|
updateGatewayList(gatewayBeanList, gateway);
|
//更新当前读取网关的列表,这个列表每次都是清空再读取
|
updateGatewayList(tempGatewayBeanList, gateway);
|
}
|
}
|
};
|
}
|
|
/**
|
* 获取搜索网关事件 这边不过滤homeId
|
*
|
* @return
|
*/
|
private EventListener getSearchGatewayEvent(final List<GatewayBean> tempGatewayBeanList) {
|
//注册搜索网关监听
|
return new EventListener() {
|
@Override
|
public void onMessage(Object msg) {
|
if (!(msg instanceof LinkResponse)) {
|
return;
|
}
|
GatewayBean gateway = getGatewayBeanByResponse((LinkResponse) msg);
|
if (gateway == null) {
|
return;
|
}
|
gateway.setIsLocalGateWay(true);//本地搜索到的网关标识为本地网关
|
//升级网关驱动 需要显示所有网关
|
//⚠️这边不需要添加到gatewayBeanList 因为这个是网关离线升级的时候的功能
|
// updateGatewayList(gatewayBeanList, gateway);
|
//更新当前读取网关的列表,这个列表每次都是清空再读取
|
updateGatewayList(tempGatewayBeanList, gateway);
|
}
|
};
|
}
|
|
/**
|
* 更新收到的网关到列表
|
*
|
* @param gatewayBeanList
|
* @param gateway 当前收到的网关
|
*/
|
void updateGatewayList(final List<GatewayBean> gatewayBeanList, GatewayBean gateway) {
|
boolean isFound = false;//是否在内存中找到网关对象
|
//找出mac一样的网关更新最新数据
|
for (int i = 0; i < gatewayBeanList.size(); i++) {
|
if (gatewayBeanList.get(i).getOid().equals(""))
|
continue;
|
if (gatewayBeanList.get(i).getOid().equals(gateway.getOid())) {
|
isFound = true;
|
gatewayBeanList.set(i, gateway);
|
// break;
|
}
|
}
|
|
//清除oid一样,mac不一样的网关缓存。一般是在网关替换的情况空间出现
|
for (int i = 0; i < gatewayBeanList.size(); i++) {
|
if (gatewayBeanList.get(i).getOid().equals("")|| gatewayBeanList.get(i).getDevice_mac().equals(""))
|
continue;
|
if (gatewayBeanList.get(i).getOid().equals(gateway.getOid()) && !gatewayBeanList.get(i).getDevice_mac().equals(gateway.getDevice_mac())
|
|| gatewayBeanList.get(i).getDevice_mac().equals(gateway.getDevice_mac()) && !gatewayBeanList.get(i).getOid().equals(gateway.getOid())) {
|
gatewayBeanList.remove(i--);
|
}
|
}
|
|
//没有找到就添加
|
if (!isFound) {
|
gatewayBeanList.add(gateway);
|
}
|
}
|
|
/**
|
* 获取网关对象
|
*
|
* @param linkResponse
|
* @return
|
*/
|
private GatewayBean getGatewayBeanByResponse(LinkResponse linkResponse) {
|
String data = linkResponse.getData();
|
if (!TextUtils.isEmpty(data)) {
|
final BaseLocalResponse<GatewayBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewayBean>>() {
|
}.getType());
|
return response.getObjects();
|
}
|
return null;
|
}
|
|
/*
|
* 绑定网关
|
* */
|
public void bindGateway(String name, String mac, String homeId, String regionUrl, String ip, boolean isEncrypt, HDLLinkCallBack callBack) {
|
String topic = String.format(TopicConstant.GATEWAY_EDIT_REMOTE, mac);
|
|
JsonObject jObject = new JsonObject();
|
jObject.addProperty("homeId", homeId);
|
jObject.addProperty("server_addr", regionUrl);
|
// jObject.addProperty("device_name", name);
|
jObject.addProperty("remote", "true");
|
|
JsonObject sendJsonObj = new JsonObject();
|
sendJsonObj.add("objects", jObject);
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
String sendStr = sendJsonObj.toString();
|
|
LinkRequest message = new LinkRequest(topic, sendStr, isEncrypt);
|
new HDLConnectHelper(ip, message, topic + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
if (callBack == null) return;
|
callBack.onSuccess("1");
|
}
|
|
@Override
|
public void onFailure() {
|
if (callBack == null) return;
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR));
|
}
|
}, true).send();
|
}
|
|
/*
|
* 初始化网关
|
* */
|
public void initializeGateway(String mac, String oid, String ip, boolean isEncrypt, HDLLinkCallBack callBack) {
|
String topic = String.format(TopicConstant.GATEWAY_INITIALIZE_REMOTE, oid);
|
|
JsonObject sendJsonObj = new JsonObject();
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
JsonObject jObject = new JsonObject();
|
jObject.addProperty("device_mac", mac);
|
sendJsonObj.add("objects", jObject);
|
String sendStr = sendJsonObj.toString();
|
|
LinkRequest message = new LinkRequest(topic, sendStr, isEncrypt);
|
new HDLConnectHelper(ip, message, topic + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
if (callBack == null) return;
|
callBack.onSuccess("1");
|
}
|
|
@Override
|
public void onFailure() {
|
if (callBack == null) return;
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR));
|
}
|
}, true).send();
|
}
|
|
/*
|
* 设置主从网关标记
|
* */
|
public void setMasterGateway(String ip, String mac, String master, boolean isEncrypt, HDLLinkCallBack callBack) {
|
String topic = String.format(TopicConstant.GATEWAY_EDIT_LOCAL, mac);
|
|
JsonObject jObject = new JsonObject();
|
jObject.addProperty("master", master);
|
|
JsonObject sendJsonObj = new JsonObject();
|
sendJsonObj.add("objects", jObject);
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
String sendStr = sendJsonObj.toString();
|
|
LinkRequest message = new LinkRequest(topic, sendStr, isEncrypt);
|
new HDLConnectHelper(ip, message, topic + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
if (callBack == null) return;
|
callBack.onSuccess("1");
|
}
|
|
@Override
|
public void onFailure() {
|
if (callBack == null) return;
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR));
|
}
|
}, true).send();
|
}
|
|
/**
|
* 设置网关入网从机模式
|
*/
|
public void AuthGateway(String ip, String mac) {
|
String topic = String.format(TopicConstant.GATEWAY_AUTH, mac);
|
|
JsonObject sendJsonObj = new JsonObject();
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
JsonObject jObject = new JsonObject();
|
jObject.addProperty("spk", "LINKDEVICE");
|
jObject.addProperty("time", "120");
|
sendJsonObj.add("objects", jObject);
|
|
|
String sendStr = sendJsonObj.toString();
|
LinkRequest message = new LinkRequest(topic, sendStr, false);
|
new HDLConnectHelper(ip, message, topic + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
}
|
|
@Override
|
public void onFailure() {
|
}
|
}, true).send();
|
}
|
|
/*
|
* 获取网关信息
|
* */
|
public void getGatewayInfo(String ip, String mac, boolean isEncrypt, HDLLinkCallBack callBack) {
|
String topic = String.format(TopicConstant.GATEWAY_GET, mac);
|
|
JsonObject sendJsonObj = new JsonObject();
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
String sendStr = sendJsonObj.toString();
|
|
LinkRequest message = new LinkRequest(topic, sendStr, isEncrypt);
|
new HDLConnectHelper(ip, message, topic + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
if (callBack == null) return;
|
callBack.onSuccess("1");
|
}
|
|
@Override
|
public void onFailure() {
|
if (callBack == null) return;
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR));
|
}
|
}, true).send();
|
}
|
|
|
|
/**
|
* 发送数据到Link网关
|
* @param ip 网关IP
|
* @param mac 网关mac
|
* @param isEncrypt 是否加密
|
* @param topic 请求主题
|
* @param jObject 负载数据<没有填null></>
|
* @param sendPath 发送路径<类名+方法名>class->methodName</>
|
*/
|
public void sendDataToLinkGateway(String ip, String mac, boolean isEncrypt,
|
String topic, Object jObject,String sendPath, HDLLinkCallBack callBack) {
|
String topicSend = topic.replace("%s", mac);
|
//组装需要发送的数据
|
String sendStr = createSendData(jObject);
|
System.out.print("sendDataToLinkGateway->"+sendPath+"->本地发送\r\n"+topicSend+"\r\n"+sendStr);
|
LinkRequest message = new LinkRequest(topicSend, sendStr, isEncrypt);
|
new HDLConnectHelper(ip, message, topicSend + "_reply", new HDLConnectHelper.HdlSocketListener() {
|
@Override
|
public void onSucceed(Object msg) {
|
if (callBack == null) return;
|
callBack.onSuccess(msg.toString());
|
System.out.print("sendDataToLinkGateway->"+sendPath+"->本地接收数据\r\n"+msg.toString());
|
}
|
|
@Override
|
public void onFailure() {
|
if (callBack == null) return;
|
callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR));
|
System.out.print("sendDataToLinkGateway->"+sendPath+"->本地接收数据->失败(-200)");
|
}
|
}, true).send();
|
}
|
|
/**
|
* 组装需要发送的数据
|
*
|
* @param jObject
|
* @return 负载数据<没有填null>
|
*/
|
public String createSendData(Object jObject) {
|
//topic = String.format(TopicConstant.GATEWAY_EDIT_LOCAL, mac);
|
JsonObject sendJsonObj = new JsonObject();
|
if (jObject != null) {
|
if (jObject instanceof JsonObject) {
|
sendJsonObj.add("objects", (JsonObject) jObject);
|
} else if (jObject instanceof JsonArray) {
|
sendJsonObj.add("objects", (JsonArray) jObject);
|
}
|
}
|
String time = String.valueOf(System.currentTimeMillis());
|
sendJsonObj.addProperty("time_stamp", time);
|
sendJsonObj.addProperty("id", IdUtils.getUUId());
|
String sendStr = sendJsonObj.toString();
|
return sendStr;
|
}
|
}
|