package com.mes.service;
|
|
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;
|
|
import java.io.DataInputStream;
|
import java.io.DataOutputStream;
|
import java.io.IOException;
|
import java.net.Socket;
|
import java.net.UnknownHostException;
|
import java.text.SimpleDateFormat;
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
|
import static com.mes.tools.HexConversion.*;
|
|
@Component
|
@Slf4j
|
public class ModbusTcp {
|
|
//同IP下会有多个协议地址 key=地址区 PlcAgreement为协议内容 plcAgreements为协议组
|
private Map<String,PlcAgreement> plcAgreement=new LinkedHashMap<String,PlcAgreement>();
|
private String Ip;
|
private int Port;
|
|
public Socket socket =null;//通讯
|
public String fileName ="";
|
public ModbusTcp(){}
|
public ModbusTcp(String Ip,int Port,String fileName){
|
this.Ip=Ip;
|
this.Port=Port;
|
this.fileName=fileName;
|
try {
|
plcAgreement.put(this.fileName,new PlcAgreement(this.fileName));
|
} catch (Exception e) {
|
log.info("file error:"+this.fileName+",{}",e.getMessage());
|
}
|
}
|
//连接
|
public void connect(){
|
try {
|
this.socket=new Socket(Ip,Port);
|
this.socket.setSoTimeout(1000);
|
}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 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())) {
|
//写入发送数据 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("写入数据异常:{}",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(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);
|
}
|
}
|
//写
|
public String message(String senddate, String address) {
|
String Herd = "0110" + address;
|
int length = senddate.length() / 4;
|
String dates = Herd + HexUtil.intTo2ByteHex(length) + HexUtil.intTo1ByteHex(length * 2) + senddate;
|
int lengths = dates.length() / 2;
|
String date = "00000000" + HexUtil.intTo2ByteHex(lengths) + dates;
|
return date;
|
}
|
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);
|
}
|
}
|