package com.bonait.bnframework.common.modbus;


import com.bonait.bnframework.common.constant.ConfigName;
import com.bonait.bnframework.common.constant.DataBus;
import com.bonait.bnframework.common.helper.DataFormat;
import com.bonait.bnframework.common.helper.I.IReadCallBack;
import com.bonait.bnframework.common.helper.I.IWriteCallBack;
import com.bonait.bnframework.common.helper.MessageLog;
import com.licheedev.modbus4android.ModbusCallback;
import com.licheedev.modbus4android.ModbusParam;
import com.licheedev.modbus4android.ModbusRespException;
import com.licheedev.modbus4android.param.TcpParam;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ReadCoilsResponse;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;


public class ModbusTcpServer {
    private static volatile ModbusTcpServer instance = null;

    public static ModbusTcpServer get() {
        ModbusTcpServer manager = instance;
        if (manager == null) {
            synchronized (ModbusTcpServer.class) {
                manager = instance;
                if (manager == null) {
                    manager = new ModbusTcpServer();
                    instance = manager;
                }
            }
        }
        return manager;
    }

    private ModbusTcpServer() {
    }

    ModbusParam param;

    private int GetAddress(String address) {
        if (address == null) return -1;
        if (address.length() > 0) {
            address = address.trim();
            if (address.toUpperCase().contains("M") && address.length() >= 4) {
                String[] res = address.substring(1).split("[.]");
                if (res != null && res.length == 2) {
                    try {
                        int firstAdd = Integer.parseInt(res[0]);
                        int endAdd = Integer.parseInt(res[1]);
                        if (endAdd >= 0 && endAdd <= 7) {
                            return (firstAdd * 8) + 320 + endAdd;
                        }
                    } catch (NumberFormatException e) {
                        return -1;
                    }
                }
            } else if (address.toUpperCase().contains("I") && address.length() >= 4) {
                String[] res = address.substring(1).split("[.]");
                if (res != null && res.length == 2) {
                    try {
                        int firstAdd = Integer.parseInt(res[0]);
                        int endAdd = Integer.parseInt(res[1]);
                        if (endAdd >= 0 && endAdd <= 7) {
                            return (firstAdd * 8) + endAdd;
                        }
                    } catch (NumberFormatException e) {
                        return -1;
                    }
                }
            } else if ((address.toUpperCase().contains("VW") || address.toUpperCase().contains("VD")) && address.length() >= 3) {
                String res = address.substring(2);
                if (res != null) {
                    try {
                        int tempAdd = Integer.parseInt(res);
                        return (tempAdd / 2) + 100;
                    } catch (NumberFormatException e) {
                        return -1;
                    }
                }
            } else {
                try {
                    return Integer.parseInt(address);
                } catch (NumberFormatException e) {
                    return -1;
                }
            }
        }
        return -1;
    }

    /**
     * 获取布尔位地址信息
     * 列：M2.5 = getBitSingleAdd("M",2,5);
     *
     * @param Prefix   地址标头
     * @param startAdd 起始地址编号
     * @param num      要获取的第几位数量
     * @return
     */
    public String getBitSingleAdd(String Prefix, int startAdd, int num) {
        if (num > 0) {
            int FirstAdd = num / 8;
            int EndAdd = num % 8;
            if (EndAdd == 0) {
                FirstAdd--;
                EndAdd = 7;
            } else {
                EndAdd--;
            }
            return Prefix + FirstAdd + startAdd + "." + EndAdd;
        }
        return "";
    }

    /**
     * Ping PLC地址是否通畅
     * @param address
     * @param pingTimes  ping的次数
     * @param timeOut  超时时间 10
     * @return
     */
    public static boolean ping2(String address, int pingTimes, int timeOut) {
        Process process = null;
        try {
            process = Runtime.getRuntime().exec( "ping "  + "-c " + pingTimes + " -w " + timeOut+ " "+address);
            InputStreamReader r = new InputStreamReader(process.getInputStream());

            LineNumberReader returnData = new LineNumberReader(r);

            String returnMsg="";

            String line = "";

            while ((line = returnData.readLine()) != null) {

                System.out.println(line);

                returnMsg += line;

            }

            if(returnMsg.indexOf("100% packet loss")!=-1){
                System.out.println("与 " +address +" 连接不畅通.");
                return  false;
            } else{

                System.out.println("与 " +address +" 连接畅通.");
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;

    }


    /**
     * 连接
     */
    public void Connect() throws InterruptedException {
        boolean status = false;
        while (!status) {
            try {
                //status为0则代表通，为1则代表不通。
                status =ping2(ConfigName.getInstance().Address,1,1);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                MessageLog.ShowInfo("设备 " + ConfigName.getInstance().Address + " 网络验证失败");
            } catch (Exception e) {
                MessageLog.ShowInfo("设备 " + ConfigName.getInstance().Address + " 网络验证失败");
            }
        }
        MessageLog.ShowInfo("设备 " + ConfigName.getInstance().Address + " PLC通讯正常,准备连接！");
        String host=ConfigName.getInstance().Address;
        int port=ConfigName.getInstance().Post;
        param = TcpParam.create(host, port)
                .setTimeout(1000)
                .setRetries(0)
                .setEncapsulated(false)
                .setKeepAlive(true);
        while (DataBus.getInstance().PlcIsConnect==false)
        {
            ConnectPLC();
            Thread.sleep(5000);


        }
    }

    /**
     * 连接PLC
     */
    public void ConnectPLC()
    {
        ModbusTcpHelper.get().init(param, new ModbusCallback<ModbusMaster>() {
            @Override
            public void onSuccess(ModbusMaster modbusMaster) {
                MessageLog.ShowInfo("设备 " + ConfigName.getInstance().Address + " 连接成功");
                DataBus.getInstance().PlcIsConnect = true;
                //1.数据中心
//                DeviceData.Get().Init();
//                //2.业务线程
//                BusinessServer.Get().Init();
//                //3.设置自动模式
//                DeviceData.Get().setHandOrAutoSwitch(true, null);
//                DeviceData.Get().setCleaningMode(false, null);//关闭自动清洗模式
//                //4.启动设备服务
//                DeviceServer.Get().Init();
//                //5.启动日志服务
//                LogServer.Get().Init();
//                //6.云订单服务
//                OrderServer.Get().Init();
//                //7.加热服务
//                ReheatServer.Get().Init();
//                //8.扫码服务
//                ScanCodeServer.Get().Init();
            }

            @Override
            public void onFailure(Throwable tr) {
                DataBus.getInstance().PlcIsConnect = false;
                MessageLog.ShowError("设备 " + ConfigName.getInstance().Address + " 连接失败：" + tr.getMessage());
            }

            @Override
            public void onFinally() {

            }
        });
    }

//    /**
//     * 重新连接Modbus
//     */
//    public void  ReconnectModbus()
//    {
//        try {
//
//            ThreadManager.Get().StartLong("PLC断线重连线程", true, new IThread() {
//                @Override
//                public void Run() throws InterruptedException {
//                    try {
//                        boolean status =ping2(ConfigName.getInstance().Address,1,1);
//                        if(status)
//                        {
//                            ModbusMaster master= ModbusTcpHelper.get().getModbusMaster();
//                            if (master==null || master.isConnected() == false) {
//                                ConnectPLC();
//                            }
//                            Thread.sleep(20000);
//                        }
//                    } catch (Exception e) {
//                        Log.i("PLC", "PLC重连接失败!"+e.getMessage());
//                    }
//                }
//                @Override
//                public void RunComplete() throws InterruptedException {
//                }
//            });
//        }catch (Exception e) {
//            MessageLog.ShowInfo("重新连接Modbus异常，" +e.getMessage());
//        }
//    }

    private Float BytesToFloat(byte[] buffers, DataFormat df) {
        if (buffers.length == 4) {
            byte[] bytes = new byte[4];
            if (df == DataFormat.ABCD) {
                bytes[0] = buffers[3];
                bytes[1] = buffers[2];
                bytes[2] = buffers[1];
                bytes[3] = buffers[0];
            } else if (df == DataFormat.CDAB) {
                bytes[0] = buffers[1];
                bytes[1] = buffers[0];
                bytes[2] = buffers[3];
                bytes[3] = buffers[2];
            } else if (df == DataFormat.BADC) {
                bytes[0] = buffers[2];
                bytes[1] = buffers[3];
                bytes[2] = buffers[0];
                bytes[3] = buffers[1];
            } else if (df == DataFormat.DCBA) {
                bytes[0] = buffers[0];
                bytes[1] = buffers[1];
                bytes[2] = buffers[2];
                bytes[3] = buffers[3];
            }
            return ByteBuffer.wrap(bytes).getFloat();
        }
        return 0.0f;
    }

    private Integer BytesToInt(byte[] buffers, DataFormat df) {
        if (buffers.length == 4) {
            byte[] bytes = new byte[4];
            if (df == DataFormat.ABCD) {
                bytes[0] = buffers[3];
                bytes[1] = buffers[2];
                bytes[2] = buffers[1];
                bytes[3] = buffers[0];
            } else if (df == DataFormat.CDAB) {
                bytes[0] = buffers[1];
                bytes[1] = buffers[0];
                bytes[2] = buffers[3];
                bytes[3] = buffers[2];
            } else if (df == DataFormat.BADC) {
                bytes[0] = buffers[2];
                bytes[1] = buffers[3];
                bytes[2] = buffers[0];
                bytes[3] = buffers[1];
            } else if (df == DataFormat.DCBA) {
                bytes[0] = buffers[0];
                bytes[1] = buffers[1];
                bytes[2] = buffers[2];
                bytes[3] = buffers[3];
            }
            return ByteBuffer.wrap(bytes).getInt();
        }
        return 0;
    }

    private byte[] IntToByte(int number) {
        int temp = number;
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return b;
    }

    private short[] IntToShorts(int value) {
        short[] res = new short[2];
        int temp = value;
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        for (int i = 0; i < res.length; i++) {
            short s0 = (short) (b[i * 2] & 0xff);// 最低位
            short s1 = (short) (b[i * 2 + 1] & 0xff);
            s1 <<= 8;
            res[i] = (short) (s0 | s1);
        }
        return res;
    }

    public static String GetString(short[] src, int start, int len) throws UnsupportedEncodingException {
        short[] temp = new short[len];
        for (int i = 0; i < len; i++) {
            temp[i] = src[i + start];
        }
        byte[] bytesTemp = shorts2Bytes(temp);
        for (int i = 0; i < bytesTemp.length; i++) {
            byte b = bytesTemp[i];
        }
        String str = new String(bytesTemp, "UTF-8");
        return str;
    }

    public static byte[] shorts2Bytes(short[] data) {
        byte[] byteValue = new byte[data.length * 2];
        for (int i = 0; i < data.length; i++) {
            byteValue[i * 2] = (byte) (data[i] & 0xff);
            byteValue[i * 2 + 1] = (byte) ((data[i] & 0xff00) >> 8);
        }
        return byteValue;
    }

    /***
     *读取实时状态
     * @param Address the address
     * @param length 读取的长度 3
     * @param callback 读取成功的回调
     */
    public void ReadStatus(String Address, int length, IReadCallBack<byte[]> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadHoldingRegistersResponse res = ModbusTcpHelper.get().syncReadHoldingRegisters(1, add, length);
            byte[] data = res.getData();
            byte[] tempData = new byte[6];
            tempData[0] = data[1];
            tempData[1] = data[0];
            tempData[2] = data[3];
            tempData[3] = data[2];
            tempData[4] = data[5];
            tempData[5] = data[4];
            if (callback != null) callback.onSuccess(tempData);
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    /***
     *读取扫码数据
     * @param Address the address
     * @param length 读取的长度
     * @param callback 读取成功的回调
     */
    public void ReadString(String Address, int length, IReadCallBack<String> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadHoldingRegistersResponse res = ModbusTcpHelper.get().syncReadHoldingRegisters(1, add, length);
            byte[] data = res.getData();
            byte[] data1 = Arrays.copyOfRange(data, 0, 18);
            //36 GUID 18 Number
            String id = "";
            try {
                byte[] tempdata = new byte[18];
                for (int i = 0; i < data1.length; i++) {
                    if (i % 2 == 0) {

                        tempdata[i + 1] = data1[i];
                    } else {
                        tempdata[i - 1] = data1[i];
                    }
                }
                id = new String(tempdata, "UTF-8").trim();
            } catch (UnsupportedEncodingException ex) {
            }
            if (callback != null) callback.onSuccess(id);
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    public void WriteString(String Address, int length, IWriteCallBack callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        short[] send = new short[length];
        for (short item : send) {
            item = 0;
        }
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
            if (callback != null)
                callback.onSuccess();
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        }
    }

    public void ReadShort(String Address, int length, IReadCallBack<short[]> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadHoldingRegistersResponse res = ModbusTcpHelper.get().syncReadHoldingRegisters(1, add, length);
            short[] data = res.getShortData();
            if (data.length == length) {
                if (callback != null) callback.onSuccess(data);
            }
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadShort onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    public void ReadBool(String Address, int length, IReadCallBack<boolean[]> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadCoilsResponse res = ModbusTcpHelper.get().syncReadCoil(1, add, length);
            boolean[] data = res.getBooleanData();
            boolean[] result = Arrays.copyOfRange(data, 0, length);
            if (result.length == length) {
                if (callback != null) callback.onSuccess(result);
            }
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadBool onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadBool onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadBool onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadBool onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadBool onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    public void ReadFloat(String Address, int length, IReadCallBack<float[]> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadHoldingRegistersResponse res = ModbusTcpHelper.get().syncReadHoldingRegisters(1, add, length);
            byte[] data = res.getData();
            float[] tempValues = new float[length];
            for (int i = 0; i < length; i++) {
                byte[] tempData = new byte[4];
                for (int m = 0; m < 4; m++) {
                    tempData[m] = data[i * 4 + m];
                }
                tempValues[i] = BytesToFloat(tempData, DataFormat.ABCD);
            }
            if (tempValues.length == length) {
                if (callback != null) callback.onSuccess(tempValues);
            }
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadFloat onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadFloat onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadFloat onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadFloat onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadFloat onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    public void ReadInt(String Address, int length, IReadCallBack<int[]> callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ReadHoldingRegistersResponse res = ModbusTcpHelper.get().syncReadHoldingRegisters(1, add, length * 2);
            byte[] data = res.getData();
            int[] tempValues = new int[length];
            for (int i = 0; i < length; i++) {
                byte[] tempData = new byte[4];
                for (int m = 0; m < 4; m++) {
                    tempData[m] = data[i * 4 + m];
                }
//                Integer a1 = tempValues[i] = BytesToInt(tempData, DataFormat.ABCD);
//                Integer a2 = tempValues[i] = BytesToInt(tempData, DataFormat.BADC);
//                Integer a3 = tempValues[i] = BytesToInt(tempData, DataFormat.CDAB);
//                Integer a4 = tempValues[i] = BytesToInt(tempData, DataFormat.DCBA);

                tempValues[i] = BytesToInt(tempData, DataFormat.BADC);

            }
            if (tempValues.length == length) {
                if (callback != null) callback.onSuccess(tempValues);
            }
        } catch (InterruptedException e) {
            MessageLog.ShowError("ReadInt onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("ReadInt onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("ReadInt onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("ReadInt onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("ReadInt onFailure，Address=" + Address + ",length=" + length + ",msg:" + e.toString());
        }
    }

    public void WriteShort(String Address, short Value, IWriteCallBack callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        short[] send = new short[1];
        send[0] = Value;
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
            if (callback != null)
                callback.onSuccess();
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        }
    }

    public void WriteBool(String Address, boolean Value, IWriteCallBack callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        try {
            ModbusTcpHelper.get().syncWriteCoil(1, add, Value);
            if (callback != null)
                callback.onSuccess();
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        }
    }

    public void WriteFloat(String Address, float Value, IWriteCallBack callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        int intBits = Float.floatToRawIntBits(Value);
        short[] send = new short[]{(short) ((intBits >> 16) & 0xffff), (short) (intBits & 0xffff)};
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);

            if (callback != null) callback.onSuccess();
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        }
    }

    public void WriteInt(String Address, int Value, IWriteCallBack callback) {
        int add = GetAddress(Address);
        if (add < 0) return;
        short[] send = IntToShorts(Value);
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
            if (callback != null) callback.onSuccess();
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
            if (callback != null) callback.onFailure(e.toString());
        }
    }

    public void WriteShort(String Address, short Value) {
        int add = GetAddress(Address);
        if (add < 0) return;
        short[] send = new short[1];
        send[0] = Value;
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteShort onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        }
    }

    public void WriteBool(String Address, boolean Value) {
        int add = GetAddress(Address);
        if (add < 0) return;

        try {
            ModbusTcpHelper.get().syncWriteCoil(1, add, Value);
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteBool onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        }
    }

    public void WriteFloat(String Address, float Value) {
        int add = GetAddress(Address);
        if (add < 0) return;
        int intBits = Float.floatToRawIntBits(Value);
        short[] send = new short[]{(short) ((intBits >> 16) & 0xffff), (short) (intBits & 0xffff)};
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteFloat onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        }
    }

    public void WriteInt(String Address, int Value) {
        int add = GetAddress(Address);
        if (add < 0) return;
        short[] send = IntToShorts(Value);
        try {
            ModbusTcpHelper.get().syncWriteRegisters(1, add, send);
        } catch (InterruptedException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ExecutionException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusTransportException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusInitException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        } catch (ModbusRespException e) {
            MessageLog.ShowError("WriteInt onFailure，Address=" + Address + ",length=" + Value + ",msg:" + e.toString());
        }
    }

}
