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, HDLLinkConfig.getInstance().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()); 
 | 
        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); 
 | 
        } 
 | 
    } 
 | 
} 
 |