New file |
| | |
| | | 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.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.BaseCallBack; |
| | | import com.hdl.sdk.link.core.callback.ModbusCallBack; |
| | | import com.hdl.sdk.link.core.callback.ZigbeeCallBack; |
| | | import com.hdl.sdk.link.core.config.HDLLinkConfig; |
| | | import com.hdl.sdk.link.gateway.HDLLinkLocalGateway; |
| | | |
| | | /** |
| | | * Created by hxb on 2021/12/8. |
| | | * 原生通讯相关接口 |
| | | */ |
| | | public class HDLModBusConnect { |
| | | |
| | | private static final String TAG="HDLModbusConnect"; |
| | | private static HDLModBusConnect instance; |
| | | /** |
| | | * 内部用,主要是处理处理掉透传主题及link主题后,还原Zigbee原生数据及主题用 |
| | | */ |
| | | private final String zigbeeAllTopic = "/Modbus"; |
| | | |
| | | /** |
| | | * 返回当前实例,不存在就创建并同时注册监听事件 |
| | | * |
| | | * @return |
| | | */ |
| | | public static HDLModBusConnect getInstance() { |
| | | if (null == instance) { |
| | | instance = new HDLModBusConnect(); |
| | | 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_MODBUS_UP, "+"), eventListener); |
| | | registerListener(String.format(TopicConstant.NATIVE_MODBUS_DOWN_REPLY, "+"), eventListener); |
| | | |
| | | // registerListener(String.format(TopicConstant.NATIVE_ZIGBEE_UP_SLAVE, "+", "+"), eventListener); |
| | | } |
| | | |
| | | /** |
| | | * 发送原生数据 |
| | | * |
| | | * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id |
| | | * @param responeTopic 回复主题 |
| | | * @param payload 发送数据 |
| | | * @param baseCallBack 结果回调 |
| | | */ |
| | | public void Send(String gatewayOidOrGatewayId,String responeTopic, String payload, final ModbusCallBack baseCallBack) { |
| | | //如果本地有链接这个网关,则用本地连接 |
| | | GatewayBean gatewayBean = HDLLinkLocalGateway.getInstance().getGatewayByOidOrGatewayId(gatewayOidOrGatewayId); |
| | | if (null == gatewayBean) { |
| | | LogUtils.i("找不到网关,Oid是" + gatewayOidOrGatewayId); |
| | | if (null != baseCallBack) { |
| | | baseCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_GATEWAY_NOT_EXIST)); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | String tempTopic = String.format(TopicConstant.NATIVE_MODBUS_DOWN, gatewayOidOrGatewayId); |
| | | LinkRequest request = new LinkRequest(tempTopic, payload, gatewayBean.getIsLocalEncrypt()); |
| | | |
| | | if ("true".equals(gatewayBean.getMaster())) { |
| | | request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN, HDLLinkConfig.getInstance().getGatewayId())); |
| | | } else { |
| | | request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN_SLAVE, HDLLinkConfig.getInstance().getGatewayId(), gatewayOidOrGatewayId)); |
| | | } |
| | | request.setReplyTopic(responeTopic); |
| | | long timeout = 2 * 1000; |
| | | |
| | | new HDLConnectHelper(timeout, 1, gatewayBean.getIp_address(), 8586, request, new HDLConnectHelper.HdlSocketListener() { |
| | | @Override |
| | | public void onSucceed(Object msg) { |
| | | // if (msg instanceof String) { |
| | | // if (null != baseCallBack) { |
| | | // baseCallBack.onSuccess(msg+""); |
| | | // } |
| | | // } |
| | | } |
| | | |
| | | @Override |
| | | public void onFailure(HDLLinkCode hdlLinkCode) { |
| | | if (null != baseCallBack) { |
| | | baseCallBack.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); |
| | | } |
| | | } |
| | | } |