New file |
| | |
| | | package com.hdl.sdk.link.core.connect; |
| | | |
| | | |
| | | import android.text.TextUtils; |
| | | |
| | | import com.hdl.link.error.HDLLinkCode; |
| | | 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.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.ModbusResponse; |
| | | import com.hdl.sdk.link.core.bean.gateway.GatewayBean; |
| | | import com.hdl.sdk.link.core.callback.ModbusCallBack; |
| | | import com.hdl.sdk.link.core.config.HDLLinkConfig; |
| | | import com.hdl.sdk.link.core.utils.ByteUtils; |
| | | 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主题后,还原modbus原生数据及主题用 |
| | | */ |
| | | private final String allTopic = "/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(allTopic, eventListener); |
| | | } |
| | | |
| | | /** |
| | | * 移除监听Zigbee原生主题及数据 |
| | | * |
| | | * @param eventListener |
| | | */ |
| | | public void removeListener(EventListener eventListener) { |
| | | if (null == eventListener) { |
| | | return; |
| | | } |
| | | EventDispatcher.getInstance().remove(allTopic, eventListener); |
| | | } |
| | | |
| | | /** |
| | | * 初始化监听事件 |
| | | */ |
| | | private void initEventListener() { |
| | | final EventListener eventListener = new EventListener() { |
| | | @Override |
| | | public void onMessage(Object msg) { |
| | | try { |
| | | if (msg instanceof LinkResponse) { |
| | | LinkResponse linkResponse = (LinkResponse) msg; |
| | | if (linkResponse.getTopic() == null || !linkResponse.getTopic().contains("custom/native/inverter/up")) { |
| | | return; |
| | | } |
| | | byte[] payload = linkResponse.getByteData(); |
| | | ModbusResponse modbusResponse = new ModbusResponse(); |
| | | String topic; |
| | | if (10 < payload.length) { |
| | | topic = String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1], payload[6], payload[7], payload[8], payload[9]}));//序号+oid |
| | | } else { |
| | | topic = String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1]})); |
| | | } |
| | | modbusResponse.setTopic(topic); |
| | | modbusResponse.setData(payload); |
| | | String oid = null; |
| | | //是否是通过主网关透传主题 |
| | | if (linkResponse.getTopic().contains("/slaveoid/")) { |
| | | oid = linkResponse.getTopic().split("/")[8]; |
| | | } else { |
| | | oid = linkResponse.getTopic().split("/")[2]; |
| | | } |
| | | modbusResponse.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表示方式 |
| | | modbusResponse.setOid(gatewayBean.getOid()); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | EventDispatcher.getInstance().post(topic, modbusResponse); |
| | | //发布Zigbee原生主题及数据 |
| | | // EventDispatcher.getInstance().post(allTopic, modbusResponse); |
| | | } |
| | | } catch (Exception e) { |
| | | LogUtils.e(TAG, "LinkResponse转ModbusResponse异常:" + 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 payload 发送数据 |
| | | * @param baseCallBack 结果回调 |
| | | */ |
| | | public void Send(String gatewayOidOrGatewayId, byte[] payload, final ModbusCallBack baseCallBack) { |
| | | Send(gatewayOidOrGatewayId, payload, 4, baseCallBack, false); |
| | | } |
| | | |
| | | /** |
| | | * 发送原生数据,子线程回调 |
| | | * |
| | | * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id |
| | | * @param payload 发送数据 |
| | | * @param baseCallBack 结果回调 |
| | | */ |
| | | public void asyncSend(String gatewayOidOrGatewayId, byte[] payload, final ModbusCallBack baseCallBack) { |
| | | Send(gatewayOidOrGatewayId, payload, 4, baseCallBack, true); |
| | | } |
| | | |
| | | /** |
| | | * 发送原生数据 |
| | | * |
| | | * @param gatewayOidOrGatewayId 目标网关的oid或者网关Id |
| | | * @param payload 发送数据 |
| | | * @param timeout 超时时间(s) |
| | | * @param baseCallBack 结果回调 |
| | | */ |
| | | public void Send(String gatewayOidOrGatewayId, byte[] payload, int timeout, final ModbusCallBack baseCallBack, boolean useSubThread) { |
| | | if (payload == null || payload.length == 0) { |
| | | if (baseCallBack != null) { |
| | | baseCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); |
| | | System.out.println("发送数据时负载数据是空的--->"); |
| | | } |
| | | return; |
| | | } |
| | | //如果本地有链接这个网关,则用本地连接 |
| | | 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.isLocalEncrypt()); |
| | | |
| | | request.setCloudTopic(String.format(TopicConstant.NATIVE_MODBUS_DOWN, gatewayBean.getGatewayId())); |
| | | if (10 < payload.length) { |
| | | request.setReplyTopic(String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1], payload[6], payload[7], payload[8], payload[9]})));//序号+oid |
| | | } else { |
| | | request.setReplyTopic(String.format("Modbus %s", ByteUtils.encodeHexString(new byte[]{payload[0], payload[1]}))); |
| | | } |
| | | long awaitTime = timeout * 1000L; |
| | | |
| | | HDLConnectHelper hdlConnectHelper = new HDLConnectHelper(awaitTime, 2, gatewayBean.getIp_address(), 8586, request, new HDLConnectHelper.HdlSocketListener() { |
| | | @Override |
| | | public void onSucceed(Object msg) { |
| | | if (msg instanceof ModbusResponse) { |
| | | if (null != baseCallBack) { |
| | | baseCallBack.onSuccess(((ModbusResponse) msg).getData()); |
| | | } |
| | | } else { |
| | | LogUtils.e("发送Modbus回调对象类型非数组类型,类型是" + msg.getClass()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void onFailure(HDLLinkCode hdlLinkCode) { |
| | | if (null != baseCallBack) { |
| | | baseCallBack.onError(HDLLinkException.getErrorWithCode(hdlLinkCode)); |
| | | } |
| | | } |
| | | }, true, gatewayBean.getDevice_mac(),true); |
| | | // hdlConnectHelper.setUseSubThread(useSubThread); |
| | | hdlConnectHelper.send(); |
| | | } |
| | | |
| | | /** |
| | | * 注册监听 |
| | | */ |
| | | 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); |
| | | } |
| | | } |
| | | } |