wjc
2025-01-07 90d5f028ccdaaaf64286f9d632cb335a4d0544b9
sdk/src/main/java/com/hdl/sdk/link/core/connect/HDLModBusConnect.java
New file
@@ -0,0 +1,225 @@
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);
        }
    }
}