package com.hdl.sdk.link.core.connect; import android.text.TextUtils; 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.LogUtils; import com.hdl.sdk.link.common.utils.ThreadToolUtils; import com.hdl.sdk.link.core.bean.LinkRequest; import com.hdl.sdk.link.core.bean.LinkResponse; import com.hdl.sdk.link.core.bean.ZigbeeResponse; import com.hdl.sdk.link.core.bean.gateway.GatewayBean; import com.hdl.sdk.link.core.callback.ZigbeeCallBack; import com.hdl.sdk.link.core.config.HDLLinkConfig; import com.hdl.sdk.link.gateway.HDLLinkLocalGateway; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by hxb on 2021/12/8. * 原生通讯相关接口 */ public class HDLZigbeeConnect { private static final String TAG="HDLZigbeeConnect"; private static HDLZigbeeConnect instance; /** * 内部用,主要是处理处理掉透传主题及link主题后,还原Zigbee原生数据及主题用 */ private final String zigbeeAllTopic = "/Zigbee"; /** * 返回当前实例,不存在就创建并同时注册监听事件 * * @return */ public static HDLZigbeeConnect getInstance() { if (null == instance) { instance = new HDLZigbeeConnect(); instance.initEventListener(); } return instance; } /** * 注册监听Zigbee所有原生主题及数据 * * @param eventListener */ public void registerListener(EventListener eventListener) { if(null==eventListener){ return; } EventDispatcher.getInstance().register(zigbeeAllTopic, eventListener); } /** * 移除监听Zigbee原生主题及数据 * * @param eventListener */ public void removeListener(EventListener eventListener) { if(null==eventListener){ return; } EventDispatcher.getInstance().remove(zigbeeAllTopic, eventListener); } /** * 初始化监听事件 */ private void initEventListener() { final EventListener eventListener = new EventListener() { @Override public void onMessage(Object msg) { try { if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; String body = linkResponse.getData(); int index = body.indexOf("{"); //zigbee回复的数据前有主题,后面才是数据 if (index <= 0) return; String zigbeeTopic = body.substring(0, index).trim(); //zigbee的负载数据 String bodyData = body.substring(index); ZigbeeResponse zigbeeResponse = new ZigbeeResponse(); zigbeeResponse.setTopic(zigbeeTopic); zigbeeResponse.setData(bodyData); String oid = null; //是否是通过主网关透传主题 if (linkResponse.getTopic().contains("/slaveoid/")) { oid = linkResponse.getTopic().split("/")[8]; } else { oid = linkResponse.getTopic().split("/")[2]; } zigbeeResponse.setOid(oid); for (GatewayBean gatewayBean : HDLLinkLocalGateway.getInstance().getGatewayList()) { if (oid.equals(gatewayBean.getGatewayId()) || oid.equals(gatewayBean.getDevice_mac()) || oid.equals(gatewayBean.getOid())) { //上面的oid可能是网关id或者mac或者是oid,不管是哪个统一使用oid表示方式 zigbeeResponse.setOid(gatewayBean.getOid()); break; } } EventDispatcher.getInstance().post(zigbeeTopic, zigbeeResponse); //发布Zigbee原生主题及数据 EventDispatcher.getInstance().post(zigbeeAllTopic, zigbeeResponse); } } catch (Exception e) { LogUtils.e(TAG,"LinkResponse转ZigbeeResponse异常:"+ e.getMessage()); } } }; // //注册直接通讯的主题,包括直接和主网关通讯或者直接和从网关通讯 // registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_DOWN_REPLY, "+"), eventListener); //注册直接通讯的主题,包括直接和主网关通讯或者直接和从网关通讯 registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_UP, "+"), eventListener); //注册通过主网关透传从网关的主题 // registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_DOWN_SLAVE_REPLY, "+", "+"), eventListener); registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_UP_SLAVE, "+", "+"), eventListener); } /** * 发送原生数据 * * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id * @param responeTopic 回复主题 * @param payload 发送数据 * @param zigbeeCallBack 结果回调 */ public void Send(String gatewayOidOrGatewayId,String responeTopic, String payload, final ZigbeeCallBack zigbeeCallBack) { //如果本地有链接这个网关,则用本地连接 GatewayBean gatewayBean = HDLLinkLocalGateway.getInstance().getGatewayByOidOrGatewayId(gatewayOidOrGatewayId); if (null == gatewayBean) { LogUtils.i("找不到网关,Oid是" + gatewayOidOrGatewayId); if (null != zigbeeCallBack) { zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GATEWAY_NOT_EXIST)); } return; } String tempTopic = String.format(TopicConstant.NATIVE_ZIGBEE_DOWN, gatewayOidOrGatewayId); LinkRequest request = new LinkRequest(tempTopic, payload, gatewayBean.getIsLocalEncrypt()); if ("true".equals(gatewayBean.getMaster())) { request.setCloudTopic(String.format(TopicConstant.NATIVE_ZIGBEE_DOWN, HDLLinkConfig.getInstance().getGatewayId())); } else { request.setCloudTopic(String.format(TopicConstant.NATIVE_ZIGBEE_DOWN_SLAVE, HDLLinkConfig.getInstance().getGatewayId(), gatewayOidOrGatewayId)); } request.setReplyTopic(responeTopic); // final boolean[] isCallBack = {false}; // //透传命令主题处理 // final EventListener eventListener = new EventListener() { // @Override // public void onMessage(Object msg) { // if (msg instanceof ZigbeeResponse) { // ZigbeeResponse linkResponse = (ZigbeeResponse) msg; // //TODO 如果配置从网关的信息,通过主网关转达,这里oid要判断下 // if (responeTopic.equals(linkResponse.getTopic())) { // isCallBack[0] = true; // removeListener(zigbeeAllTopic, this); // if (null != zigbeeCallBack) { // zigbeeCallBack.onSuccess(linkResponse.getData()); // } // } // } // } // }; // //注册监听 // registerListener(zigbeeAllTopic, eventListener); long timeout = 8 * 1000; /** * 需要特殊处理一些主题 需要延长超时时间 */ if (responeTopic.equals("Bind/SetBind_Respon") || responeTopic.equals("Bind/ClearBindInfo_Respon")) { timeout = 20 * 1000; } // //一定时间后还没有接收到数据,就回调失败 // ScheduledExecutorService scheduledExecutorService = ThreadToolUtils.getInstance().newScheduledThreadPool(1); // scheduledExecutorService.schedule(new Runnable() { // @Override // public void run() { // removeListener(zigbeeAllTopic, eventListener); // scheduledExecutorService.shutdownNow(); // if (!isCallBack[0]) { // if (null != zigbeeCallBack) { // zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GET_Zigbee_FAILURE_ERROR)); // } // } // } // }, timeout, TimeUnit.SECONDS); new HDLConnectHelper(timeout, 1, gatewayBean.getIp_address(), 8586, request, new HDLConnectHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if (msg instanceof String) { if (null != zigbeeCallBack) { zigbeeCallBack.onSuccess(msg+""); } } } @Override public void onFailure(HDLLinkCode hdlLinkCode) { if (null != zigbeeCallBack) { zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(hdlLinkCode)); } } }, true).send(); } /** * 发送原生透传命令数据 * * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id * @param responeTopic 回复主题 * @param payload 发送数据 * @param zigbeeCallBack 结果回调 */ public void SendThrough(String gatewayOidOrGatewayId, String responeTopic, String payload, final ZigbeeCallBack zigbeeCallBack) { // //如果本地有链接这个网关,则用本地连接 // GatewayBean gatewayBean = HDLLinkLocalGateway.getInstance().getGatewayByOidOrGatewayId(gatewayOidOrGatewayId); // if (null == gatewayBean) { // LogUtils.i("找不到网关,Oid是" + gatewayOidOrGatewayId); // if (null != zigbeeCallBack) { // zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GATEWAY_NOT_EXIST)); // } // return; // } // boolean isLocal = gatewayBean.getIsLocalGateway(); // //如果是本地通讯 // if (isLocal == true) { // // String tempTopic = String.format("/user/%s/custom/native/zigbee/down", gatewayOidOrGatewayId); // String tempTopicReply = String.format("/user/%s/custom/native/zigbee/up", gatewayOidOrGatewayId); // // final boolean[] isCallBack = {false}; // //透传命令主题处理 // final EventListener eventListener = new EventListener() { // @Override // public void onMessage(Object msg) { // if (msg instanceof LinkResponse) { // LinkResponse linkResponse = (LinkResponse) msg; // //TODO 如果配置从网关的信息,通过主网关转达,这里oid要判断下 // String body = getZigbeeData(responeTopic, linkResponse); // if (null != body) { // isCallBack[0] = true; // removeListener(tempTopicReply, this); // if (null != zigbeeCallBack) { // zigbeeCallBack.onSuccess(body); // } // } // } // } // }; // //注册监听 // registerListener(tempTopicReply, eventListener); // // //一定时间后还没有接收到数据,就回调失败 // ScheduledExecutorService scheduledExecutorService = ThreadToolUtils.getInstance().newScheduledThreadPool(1); // scheduledExecutorService.schedule(new Runnable() { // @Override // public void run() { // removeListener(tempTopicReply, eventListener); // scheduledExecutorService.shutdownNow(); // if (!isCallBack[0]) { // if (null != zigbeeCallBack) { // zigbeeCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GET_Zigbee_FAILURE_ERROR)); // } // } // } // }, 5, TimeUnit.SECONDS); // // //本地发送 // LinkRequest request = new LinkRequest(tempTopic, payload, gatewayBean.getIsLocalEncrypt()); // new HDLConnectHelper(gatewayBean.getIp_address(), request,true).send(); // } else { // //请求主题 // String tempTopic = null; // //回复主题 // String tempTopicReply = null; // // //远程发送 // if ("true".equals(gatewayBean.getMaster())) { // tempTopic = String.format("/user/%s/custom/native/zigbee/down", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId()); // tempTopicReply = String.format("/user/%s/custom/native/zigbee/up", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId()); // } else { // tempTopic = String.format("/user/%s/custom/native/zigbee/slaveoid/%s/down", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId(), gatewayOidOrGatewayId); // tempTopicReply = String.format("/user/%s/custom/native/zigbee/slaveoid/%s/up", com.hdl.sdk.link.core.config.HDLLinkConfig.getInstance().getGatewayId(), "+"); // } // //TODO 后续完善云端的发送接收方法 // } } /** * 处理zigbee回复的数据 * * @param responeTopic 回复主题 * @param linkResponse 回复的透传数据 */ private static String getZigbeeData(String responeTopic, LinkResponse linkResponse) { //主题为空不处理 if(TextUtils.isEmpty(responeTopic)){ return null; } String body = linkResponse.getData(); int index = body.indexOf("{"); //zigbee回复的数据前有主题,后面才是数据 if (index <= 0) return null; String zigbeeTopic = body.substring(0, index).trim(); //zigbee的负载数据 String bodyData = body.substring(index); //不是当前请求的数据,不处理 if (!zigbeeTopic.startsWith(responeTopic)) { return null; } return bodyData; //Zigbee以前的接收逻辑 // HdlZbGatewayReceiveLogic.Current.ZigbeeOldReceiveLogic(reportTopic, bodyData, gatewayMac); } /** * 注册监听 */ static void registerListener(String responseTopic, EventListener eventListener) { if (!TextUtils.isEmpty(responseTopic)) { EventDispatcher.getInstance().register(responseTopic, eventListener); } } /** * 移除监听 */ static void removeListener(String responseTopic, EventListener eventListener) { if (!TextUtils.isEmpty(responseTopic)) { EventDispatcher.getInstance().remove(responseTopic, eventListener); } } }