严智鑫
2024-12-03 def1eb8623e1444164ae4bce9179d011a89b8c5e
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/ModbusTcp.java
@@ -2,6 +2,7 @@
import com.mes.tools.HexConversion;
import com.mes.utils.HexUtil;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -17,6 +18,8 @@
import java.util.LinkedHashMap;
import java.util.Map;
import static com.mes.tools.HexConversion.*;
@Component
@Slf4j
public class ModbusTcp {
@@ -27,73 +30,173 @@
    private int Port;
    public Socket socket =null;//通讯
    ModbusTcp(){}
    public ModbusTcp(String Ip,int Port){
    public String fileName ="";
    public ModbusTcp(){}
    public ModbusTcp(String Ip,int Port,String fileName){
        this.Ip=Ip;
        this.Port=Port;
        this.fileName=fileName;
        try {
            socket=new Socket(Ip,Port);
        }catch (UnknownHostException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
            plcAgreement.put(this.fileName,new PlcAgreement(this.fileName));
        } catch (Exception e) {
            log.info("file error:"+this.fileName+",{}",e.getMessage());
        }
    }
    //连接
    //@Scheduled(fixedDelay = 1000)
    public void a()throws Exception{
        //read();
        log.info("123");
    public void connect(){
        try {
            this.socket=new Socket(Ip,Port);
            this.socket.setSoTimeout(2000);
        }catch (Exception e) {
            log.info("The IP address of the host cannot be determined:{}",e.getMessage());
        }
    }
    //关闭连接
    public void close(){
        try {
            this.socket.close();
        }catch (Exception e) {
            //log.info("连接关闭异常:{}",e.getMessage());
        }
    }
    //返回连接状态
    public boolean isConnect(){
        try {
            this.socket.isConnected();
        }catch (Exception e) {
            log.info("Connection status exception:{}",this.socket);
        }
        return false;
    }
    //读取数据
    public void read(PlcAgreement plcAgreement)throws Exception{
        int bufSizes = 0;
        byte[] msgs = new byte[2048];
        //写入读取地址
        DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
        outToServer.write(HexConversion.stringToInt(plcAgreement.requestHead));
        outToServer.flush();
        //读取内容
        DataInputStream in = new DataInputStream(socket.getInputStream());
        bufSizes = in.read(msgs);
        String message = HexConversion.byteToHexString(bufSizes, msgs);//十进制字节数组转十六进制字符串
        //获取参数值
        Map<String, PlcParameter> plcParameters=plcAgreement.getPlcParameters();
        for (String key:plcParameters.keySet()){
            PlcParameter plcParameter=plcParameters.get(key);
            if("bit".equals(plcParameter.getType())){
                byte font=msgs[plcParameter.getAddressStart()];
                String[] fontBitString=String.format("%8s", Integer.toBinaryString((int)font)).replace(" ", "0").split("");
                byte[] bit=new byte[1];
                bit[0]=Byte.parseByte(fontBitString[plcParameter.getAddressLength()]);
                plcParameter.setReadByte(bit);
            }else{
                plcParameter.setReadByte(Arrays.copyOfRange(msgs,plcParameter.getAddressStart(),(plcParameter.getAddressStart()+plcParameter.getAddressLength())));
    public boolean read(PlcAgreement plcAgreement){
        try {
            if (!this.socket.isConnected()){
               // log.info("通讯连接失败:{}",this.socket.isConnected());
                return false;
            }
            int bufSizes = 0;
            byte[] msgs = new byte[2048];
            byte[] content = new byte[2048];
            //写入读取地址
            DataOutputStream outToServer = new DataOutputStream(this.socket.getOutputStream());
            outToServer.write(HexConversion.stringToInt(plcAgreement.requestHead));
            outToServer.flush();
            //读取内容
            DataInputStream in = new DataInputStream(this.socket.getInputStream());
            bufSizes = in.read(msgs);
            if(bufSizes<plcAgreement.plcAddressLength+9){
                log.info("Read byte length <1:{},content:{}",bufSizes,msgs);
                return false;
            }
            content=Arrays.copyOfRange(msgs,9,2048);
            //获取参数值
            Map<String, PlcParameter> plcParameters=plcAgreement.getPlcParameters();
            for (String key:plcParameters.keySet()){
                PlcParameter plcParameter=plcParameters.get(key);
                if("bit".equals(plcParameter.getType())){
                    byte font=content[plcParameter.getAddressStart()];
                    String[] fontBitString=String.format("%8s", Integer.toBinaryString((int)font)).replace(" ", "0").split("");
                    byte[] bit=new byte[1];
                    bit[0]=Byte.parseByte(fontBitString[plcParameter.getAddressLength()]);
                    plcParameter.setReadByte(bit);
                }else{
                    plcParameter.setReadByte(Arrays.copyOfRange(content,plcParameter.getAddressStart(),(plcParameter.getAddressStart()+plcParameter.getAddressLength())));
                }
            }
            return true;
        }catch (Exception e) {
            //log.info("读取异常:{}",plcAgreement);
        }
        return false;
    }
    //写入数据
    public void write(PlcParameter plcParameter){
        try {
            if (plcParameter.getWriteValue() != null && !"".equals(plcParameter.getWriteValue())) {
                //写入发送数据
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                out.write(HexConversion.stringToInt(plcParameter.getWriteValue().toString()));
                //写入发送数据 0000 0000 0009 0110 0024 0001 02 0006
                byte []sendByte=new byte[13+plcParameter.getAddressLength()];
                byte []sendLength=intToBytesDesc(7+plcParameter.getAddressLength(),2);
                byte []sendAddress=intToBytesDesc(plcParameter.getAddressStart()/2,2);
                byte []sendFontLength=intToBytesDesc(plcParameter.getAddressLength()/2,2);
                byte []sendContent=plcParameter.getWriteByte();
                //byte []sendContent=intToBytesDesc(Integer.parseInt(plcParameter.getWriteValue().toString()),plcParameter.getAddressLength());
                sendByte[4]=sendLength[0];
                sendByte[5]=sendLength[1];
                sendByte[6]=(byte)1;
                sendByte[7]=(byte)16;
                sendByte[8]=sendAddress[0];
                sendByte[9]=sendAddress[1];
                sendByte[10]=sendFontLength[0];
                sendByte[11]=sendFontLength[1];
                sendByte[12]=(byte)plcParameter.getAddressLength();
                for(int i=0;i<sendContent.length;i++){
                    sendByte[i+13]=sendContent[i];
                }
                log.info("sendByte:{}",sendByte);
                DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());
                out.write(sendByte);
                out.flush();
                //log.info("sendByte:{}",sendByte);
            }
        } catch (IOException e) {
            log.info("写入数据异常");
            log.info("写入数据异常:{}",plcParameter);
            throw new RuntimeException(e);
        }
    }
    //数据处理
    public void handleData(PlcParameter plcParameter){
        //写入发送数据 0000 0000 0009 0110 0024 0001 02 0006
        try {
            int sendLength=plcParameter.getAddressLength()+7;//发送长度
            byte [] addressLength=intToBytesDesc(plcParameter.getAddressLength(),1);//字节长度
            byte [] addressLengthFont=intToBytesDesc((plcParameter.getAddressLength()/2),2);//字长度
            byte start[]=intToBytesDesc(plcParameter.getAddressStart()/2,2);//起始地址
            byte content[]=intToBytesDesc(Integer.valueOf(plcParameter.getWriteValue().toString()) ,2);//起始地址
            if (sendLength>14&&
                    addressLength.length>0&&
                    addressLengthFont.length>1&&
                    start.length>1&&
                    content.length>1){
                byte head[]=new byte[]{0,0,0,(byte)sendLength,1,16,start[0],start[1],addressLengthFont[0],addressLengthFont[1],addressLength[0],content[0],content[1]};
                this.write(head);
            }else{
                log.info("发送内容不符合: 字节长度 {},字长度:{},起始地址,{},内容:{}",addressLength,addressLengthFont,start,content);
            }
        } catch (Exception e) {
            log.info("数据处理异常: 内容 {}",plcParameter);
        }
    }
    //写入数据
    public void write(String key,String writeValue)throws Exception{
        if (writeValue != null && !"".equals(writeValue)) {
            //写入发送数据
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.write(HexConversion.stringToInt(writeValue));
            out.flush();
    public void write(byte []sendByte){
        try {
            if (sendByte != null) {
                //写入发送数据
                DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());
                out.write(sendByte);
                out.flush();
                log.info("写入成功: 内容 {}",sendByte);
            }
        } catch (Exception e) {
            log.info("写入失败: 内容 {}",sendByte);
        }
    }
    //写入数据String
    public void writeString(String sendString,String startAddress){
        try {
            String result=message(sendString,startAddress);
            if (result != null && !"".equals(result)) {
                //写入数据
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                out.write(HexUtil.stringToInt(result));
                out.flush();
                log.info("写入成功:地址 {},内容 {},字节:{}",startAddress,sendString,HexUtil.stringToInt(result));
                //this.close();
            }
        } catch (Exception e) {
            log.info("写入异常:地址 {},内容 {}",startAddress,sendString);
        }
    }
    //写
@@ -108,4 +211,13 @@
    public PlcAgreement getPlcAgreement(String key){
        return plcAgreement.get(key);
    }
    public void consoleLogInfo(PlcAgreement thisPlcAgreement){
        String logInfo=this.fileName+"  ";
        Map<String,PlcParameter> plcParameterMap=thisPlcAgreement.getPlcParameters();
        for (String key:plcParameterMap.keySet()) {
            logInfo+=key+":"+plcParameterMap.get(key).getValueString()+",";
        }
        log.info(logInfo);
    }
}