package damtest;

import java.net.InetAddress;

import net.wimpi.modbus.io.ModbusRTUTCPTransaction;
import net.wimpi.modbus.msg.ReadCoilsRequest;
import net.wimpi.modbus.msg.ReadCoilsResponse;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.msg.ReadInputRegistersRequest;
import net.wimpi.modbus.msg.ReadInputRegistersResponse;
import net.wimpi.modbus.msg.ReadMultipleRegistersRequest;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.msg.WriteCoilRequest;
import net.wimpi.modbus.net.RTUTCPMasterConnection;
import net.wimpi.modbus.procimg.InputRegister;
import net.wimpi.modbus.util.BitVector;

public class JYDAMEquip {

	String ip = "192.168.1.232";
	int port = 10000;
	int slaveID = 254;
	RTUTCPMasterConnection Conn;
	int ErrorCnt = 0;

	public void Init(String _ip, int _port, int _slaveID) {
		ip = _ip;
		port = _port;
		slaveID = _slaveID;
	}

	public boolean BeginConnect() {
		try {
			InetAddress addr = InetAddress.getByName(ip);

			// creat new tcp
			Conn = new RTUTCPMasterConnection(addr, port);
			Conn.setTimeout(3000);
			Conn.connect();

		} catch (Exception e) {
			e.printStackTrace();
		}

		return IsConnect();
	}

	public boolean IsConnect() {
		if (ErrorCnt > 10) {
			ErrorCnt = 0;
			if (Conn == null)
				return false;
			Conn.close();
			Conn = null;
		}
		if (Conn == null)
			return false;
		return Conn.isConnected();
	}

	public boolean DisConnect() {
		if (Conn == null)
			return false;
		Conn.close();
		return IsConnect();
	}

	// 继电器的寄存器默认起始地址为0， 一般只需要提供继电器数量即可。
	public BitVector readDO(int count) {
		BitVector data = null;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return data;
			}

			if (count == 0)
				return data;

			// 默认第一个继电器的地址为0
			ReadCoilsRequest req = new ReadCoilsRequest(0, count);

			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			trans.execute();

			ReadCoilsResponse res = ((ReadCoilsResponse) trans.getResponse());

			data = res.getCoils();

			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	// 继电器的寄存器默认起始地址为0， 0为第一路继电器。  1为第二个继电器 
	public int readSignalDO(int regAddr) {
		int data = 0;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return -1;
			}

			ReadCoilsRequest req = new ReadCoilsRequest(regAddr, 1);

			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			trans.execute();

			ReadCoilsResponse res = ((ReadCoilsResponse) trans.getResponse());

			if (res.getCoils().getBit(0)) {
				data = 1;
			}

			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	// regstart 为继电器的地址，  0为 个   3为第 
	// value为操作继电器的状态，  0为关闭  非0为打 器
	public void writeSignalDO(int regAddr, int value) {
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return;
			}

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			WriteCoilRequest req = new WriteCoilRequest(regAddr, value == 0 ? false : true);

			req.setUnitID(slaveID);
			trans.setRequest(req);

			trans.execute();
			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}
	}

	// 光耦输入为DI的状态，默认只需要提供光耦的数量即可
	public BitVector readDI(int count) {
		BitVector data = null;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return data;
			}
			if (count == 0)
				return data;

			// 第一个参数是寄存器的地址，第二个参数时读取多少个
			ReadInputDiscretesRequest req = new ReadInputDiscretesRequest(0, count);

			// 这里设置的Slave Id, 读取的时候这个很重要
			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			// 执行查询
			trans.execute();

			// 得到结果
			ReadInputDiscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse();

			data = res.getDiscretes();

			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	// 光耦输入为DI的状态，读取单路光耦的状态  不常使用
	public int readSignalDI(int regAddr) {
		int data = 0;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return -1;
			}

			// 第一个参数是寄存器的地址，第二个参数时读取多少个
			ReadInputDiscretesRequest req = new ReadInputDiscretesRequest(regAddr, 1);

			// 这里设置的Slave Id, 读取的时候这个很重要
			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			// 执行查询
			trans.execute();

			// 得到结果
			ReadInputDiscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse();

			if (res.getDiscretes().getBit(0)) {
				data = 1;
			}

			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	// 读取模拟量的数据，
	//默认设备一般保留 int_16 类型的寄存器，起始地址为0，长度为实际数量。
	public int[] readAI(int count) {
		int[] data = null;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return data;
			}

			if (count == 0)
				return data;

			// 这里重点说明下，这个地址和数量一定要对应起来
			ReadInputRegistersRequest req = new ReadInputRegistersRequest(0, count);

			// 这个SlaveId??定要正确
			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			trans.execute();

			ReadInputRegistersResponse res = (ReadInputRegistersResponse) trans.getResponse();

			InputRegister[] rst = res.getRegisters();
			if (rst.length != count)
				return data;
			data = new int[count];
			for (int i = 0; i < count; i++)
				data[i] = rst[i].getValue();

			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	//读取单路模拟量的数值。第一个通道的地址为0
	public int readSignalAI(int regAddr) {
		int data = 0;

		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return -1;
			}

			// 这里重点说明下，这个地址和数量一定要对应起来
			ReadInputRegistersRequest req = new ReadInputRegistersRequest(regAddr, 1);

			// 这个SlaveId??定要正确
			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			trans.execute();

			ReadInputRegistersResponse res = (ReadInputRegistersResponse) trans.getResponse();

			data = res.getRegisterValue(0);
			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

	//控制所有继电器的状态
	public void writeAllDO(int regAddr, BitVector value) {
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return;
			}

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			WriteMultipleCoilsRequest req = new WriteMultipleCoilsRequest(regAddr, value);

			req.setUnitID(slaveID);
			trans.setRequest(req);

			trans.execute();
			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}
	}

	public int readRegister(int regAddr) {
		int data = 0;
		try {
			if (IsConnect() == false) {
				if (BeginConnect() == false)
					return -1;
			}
			ReadMultipleRegistersRequest req = new ReadMultipleRegistersRequest(regAddr, 1);
			req.setUnitID(slaveID);

			ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn);

			trans.setRequest(req);

			trans.execute();

			ReadMultipleRegistersResponse res = (ReadMultipleRegistersResponse) trans.getResponse();

			data = res.getRegisterValue(0);
			ErrorCnt = 0;
		} catch (Exception e) {
			e.printStackTrace();
			ErrorCnt++;
		}

		return data;
	}

}
