Browse Source

modbus运行优化

java8
wenkuan.shi 1 year ago
parent
commit
0c5b4af410
  1. 215
      src/main/java/com/xujie/sys/modules/reader/service/impl/ModbusCommunicateServiceImpl.java

215
src/main/java/com/xujie/sys/modules/reader/service/impl/ModbusCommunicateServiceImpl.java

@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateMapper,ModbusCommunicateEntity> implements ModbusCommunicateService {
public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateMapper, ModbusCommunicateEntity> implements ModbusCommunicateService {
@Autowired
private GetInformationForExcelMapper getInformationForExcelMapper;
@ -49,55 +49,66 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
@Override
public void getInfoByModbus() {
log.info("modbus请求开始解析");
long startTime = System.nanoTime();
LambdaQueryWrapper<EquipmentFolderLocation> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(EquipmentFolderLocation::getSuffix, "PLC");
EquipmentFolderLocation folderLocation = equipmentFolderLocationService.getOne(queryWrapper);
ModbusCommunicateEntity one = this.getOne(new LambdaQueryWrapper<>());
if (one == null) {
if (folderLocation == null) {
log.info("设备信息未填");
return;
}
String modbusIp = folderLocation.getIp();
if (StringUtils.equals(modbusIp,"127.0.0.1") || StringUtils.isEmpty(modbusIp)){
if (StringUtils.equals(modbusIp, "127.0.0.1") || StringUtils.isEmpty(modbusIp)) {
return;
}
int modbusPort = folderLocation.getPort();
int registerAddress = folderLocation.getRegisterAddress();
int registerNum = folderLocation.getRegisterNum();
int unitId = folderLocation.getUnitId();
int registerAddressInspection=folderLocation.getRegisterAddressInspection();
int registerNumInspection=folderLocation.getRegisterNumInspection();
int registerAddressInspection = folderLocation.getRegisterAddressInspection();
int registerNumInspection = folderLocation.getRegisterNumInspection();
//获取单号
String inspectionOrderNumber = getInspectionOrderNumber(modbusIp, modbusPort, registerAddressInspection, registerNumInspection, unitId);
log.info("最终获取的检验单号是: {}" ,inspectionOrderNumber);
if (StringUtils.isEmpty(inspectionOrderNumber)|| inspectionOrderNumber.trim().equals("")){//判断是空或者是寄存器是零的话就返回
log.info("没有值或者已被清零");
String inspectionOrderNumber = getInspectionOrderNumber(modbusIp, modbusPort, registerAddressInspection, registerNumInspection, unitId).trim();
if (StringUtils.isEmpty(inspectionOrderNumber) || inspectionOrderNumber.trim().equals("")) {//判断是空或者是寄存器是零的话就返回
return;
}
//应为modbus每次取值都是有一个固定范围,所以这里如果超过固定范围就要做处理
int number=100;
int divisor=registerNum/100;
int remainder=registerNum % 100;
List<List<Float>> floatValues=new ArrayList<>();
if (remainder!=0){
for (int i = 1; i <= (divisor + 1); i++) {
//获取值
List<Float> floatValue = getValue(modbusIp, modbusPort, registerAddress, number, unitId);
floatValues.add(floatValue);
if (i==divisor + 1){
number=remainder;
}
registerAddress=registerAddress+number;
}
}else {
for (int i = 1; i <= divisor ; i++) {
List<Float> floatValue = getValue(modbusIp, modbusPort, registerAddress, number, unitId);
floatValues.add(floatValue);
registerAddress=registerAddress+number;
}
}
//获取对应检验单号的值
List<List<Float>> floatValues = getValue(modbusIp, modbusPort, registerAddress, registerNum, unitId);
// int number=100;
// int divisor=registerNum/100;
// int remainder=registerNum % 100;
// List<List<Float>> floatValues=new ArrayList<>();
// long startTime1 = System.nanoTime();
// if (remainder!=0){
// for (int i = 1; i <= (divisor + 1); i++) {
// //获取值
//// List<Float> floatValue = getValue(modbusIp, modbusPort, registerAddress, number, unitId);
// //如果有值那么在获取值之后清零
// if (CollectionUtils.isNotEmpty(floatValue)){
//// deleteForModbus(modbusIp, modbusPort, registerAddress, number, unitId);
// }
// floatValues.add(floatValue);
// if (i==divisor + 1){
// number=remainder;
// }
// registerAddress=registerAddress+number;
// }
// }else {
// for (int i = 1; i <= divisor ; i++) {
// List<Float> floatValue = getValue(modbusIp, modbusPort, registerAddress, number, unitId);
// //如果有值那么在获取值之后清零
// if (CollectionUtils.isNotEmpty(floatValue)){
//// deleteForModbus(modbusIp, modbusPort, registerAddress, number, unitId);
// }
// floatValues.add(floatValue);
// registerAddress=registerAddress+number;
// }
// long endTime1= System.nanoTime();
// long elapsedTimeInNanos1 =endTime1-startTime1;
// double elapsedTimeInSeconds1 = (double) elapsedTimeInNanos1 / 1_000_000_000.0;
// log.info("值获取/清零时间: {}", elapsedTimeInSeconds1);
// }
//判断这个批次号应该是多少
LambdaQueryWrapper<EquipmentDataDetail> query = new LambdaQueryWrapper<>();
@ -123,7 +134,7 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
batchNo = equipments.get(equipments.size() - 1).getBatchNo();
}
}
int num =1;
int num = 1;
List<EquipmentDataDetail> detailList = new ArrayList<>();
for (List<Float> aFloat : floatValues) {
@ -141,13 +152,18 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
num++;
}
}
log.info("num: {}",num);
long endTime = System.nanoTime();
long elapsedTimeInNanos = endTime - startTime;
double elapsedTimeInSeconds = (double) elapsedTimeInNanos / 1_000_000_000.0;
log.info("总时间: {}", elapsedTimeInSeconds);
log.info("num: {}", num);
saveInformation(detailList);
}
//获取具体值
//应为modbus 寄存器每次最大请求一百多个 这里一次连接多次分多次请求
//获取具体值(连接modbus)
@Transactional
public List<Float> getValue(String modbusIp, int modbusPort, int registerAddress, int registerNum, int unitId) {
public List<List<Float>> getValue(String modbusIp, int modbusPort, int registerAddress, int registerNum, int unitId) {
log.info("modbus请求开始解析");
// String modbusIp = "172.26.58.222";
// int modbusPort = 502;
@ -155,14 +171,56 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
// int registerNum = 20;
// int unitId = 1;
log.info("获取modbus设备ip-端口-地址值-数量-unitId:" + modbusIp + "-" + modbusPort + "-" + registerAddress + "-" + registerNum + "-" + unitId);
ArrayList<Float> floats = new ArrayList<Float>();
List<List<Float>> floatValues = new ArrayList<>();
try {
InetAddress ipAddress = InetAddress.getByName(modbusIp);
// 连接到Modbus设备
TCPMasterConnection connection = new TCPMasterConnection(ipAddress);
connection.setPort(modbusPort);
connection.connect();
//应为modbus每次取值都是有一个固定范围,所以这里如果超过固定范围就要做处理
int number = 100;
int divisor = registerNum / 100;
int remainder = registerNum % 100;
if (remainder != 0) {
for (int i = 1; i <= (divisor + 1); i++) {
//获取值
List<Float> floatValue = getResponseMessage(registerAddress, number, unitId, connection);
//如果有值那么在获取值之后清零
if (CollectionUtils.isNotEmpty(floatValue)) {
deleteForModbus(registerAddress, number, unitId, connection);
}
floatValues.add(floatValue);
if (i == divisor + 1) {
number = remainder;
}
registerAddress = registerAddress + number;
}
} else {
for (int i = 1; i <= divisor; i++) {
List<Float> floatValue = getResponseMessage(registerAddress, number, unitId, connection);
//如果有值那么在获取值之后清零
if (CollectionUtils.isNotEmpty(floatValue)) {
deleteForModbus(registerAddress, number, unitId, connection);
}
floatValues.add(floatValue);
registerAddress = registerAddress + number;
}
}
// 关闭连接
connection.close();
log.info("关闭连接");
} catch (Exception e) {
log.error("连接Modbus设备时出现异常: {}", e.getMessage());
e.printStackTrace();
}
return floatValues;
}
//获取值(请求modbus获取)
public List<Float> getResponseMessage(int registerAddress, int registerNum, int unitId, TCPMasterConnection connection) {
ArrayList<Float> floats = new ArrayList<Float>();
try {
// 创建一个Modbus TCP请求
ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(registerAddress, registerNum);
request.setUnitID(unitId); // 设置Modbus设备的Unit ID
@ -184,34 +242,20 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
ArrayList<Integer> hex = new ArrayList<>();
InputRegister[] registers = response.getRegisters();
for (InputRegister register : registers) {
short value = register.toShort();
short value = register.toShort();
int hexValue = value & 0xFFFF;
log.info("获取的值是: {},value: {}",hexValue,value);
log.info("获取的值是: {},value: {}", hexValue, value);
hex.add(hexValue);
}
for (int i = 0; i < hex.size(); i+=2) {
int hexI= (hex.get(i) << 16 ) | ( hex.get(i+1)& 0xFFFF);
for (int i = 0; i < hex.size(); i += 2) {
int hexI = (hex.get(i) << 16) | (hex.get(i + 1) & 0xFFFF);
float floatValue = Float.intBitsToFloat(hexI);
floats.add(floatValue);
log.info("最终值是: {}" ,floatValue);
}
// 准备写入的寄存器数组
Register[] writeRegisters = new Register[registerNum];
for (int i = 0; i < registerNum; i++) {
writeRegisters[i] = new SimpleRegister(0); // 设置为0或者其他你需要写入的值
log.info("最终值是: {}", floatValue);
}
WriteMultipleRegistersRequest writeRequest = new WriteMultipleRegistersRequest(registerAddress, writeRegisters);
writeRequest.setUnitID(unitId);
ModbusTCPTransaction writeTransaction = new ModbusTCPTransaction(connection);
writeTransaction.setRequest(writeRequest);
writeTransaction.execute();
log.info("寄存器已清零");
} else {
log.info("处理数据出现异常");
}
// 关闭连接
connection.close();
log.info("关闭连接");
} catch (Exception e) {
log.error("连接Modbus设备时出现异常: {}", e.getMessage());
e.printStackTrace();
@ -221,7 +265,7 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
//获取检验单号
@Transactional
public String getInspectionOrderNumber(String modbusIp, int modbusPort,int registerAddress,int registerNum,int unitId){
public String getInspectionOrderNumber(String modbusIp, int modbusPort, int registerAddress, int registerNum, int unitId) {
log.info("modbus请求开始解析");
// String modbusIp = "172.26.58.222";
// int modbusPort = 502;
@ -229,7 +273,8 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
// int registerNum = 11;
// int unitId = 1;
log.info("获取modbus设备ip-端口-地址值-数量-unitId:" + modbusIp + "-" + modbusPort + "-" + registerAddress + "-" + registerNum + "-" + unitId);
String finalString="";
long startTime = System.nanoTime();
String finalString = "";
try {
InetAddress ipAddress = InetAddress.getByName(modbusIp);
@ -238,11 +283,11 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
connection.setPort(modbusPort);
connection.connect();
// 创建一个Modbus TCP请求
ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(registerAddress, registerNum);
request.setUnitID(unitId); // 设置Modbus设备的Unit ID
// 创建一个Modbus TCP事务
ModbusTCPTransaction transaction = new ModbusTCPTransaction(connection);
transaction.setRequest(request);
@ -253,13 +298,19 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
// 获取响应
ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse) transaction.getResponse();
long endTime = System.nanoTime();
long elapsedTimeInNanos = endTime - startTime;
double elapsedTimeInSeconds = (double) elapsedTimeInNanos / 1_000_000_000.0;
log.info("时间elapsedTimeInSeconds: {}", elapsedTimeInSeconds);
log.info("打印响应的数据: {}", response.getMessage());
if (response != null) {
InputRegister[] registers = response.getRegisters();
ArrayList<byte[]> byteArrayList = new ArrayList<byte[]>();
for (InputRegister register : registers) {
short value = register.toShort();
log.info("short类型: {}",value);
short value = register.toShort();
log.info("short类型: {}", value);
// 创建一个长度为 2 的字节数组
byte[] byteArray = new byte[2];
// short 值转换成字节数组
@ -277,18 +328,12 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
finalString = stringBuilder.toString();
log.info("转换后的字符串: {}", finalString);
// 准备写入的寄存器数组
Register[] writeRegisters = new Register[registerNum];
for (int i = 0; i < registerNum; i++) {
writeRegisters[i] = new SimpleRegister(0); // 设置为0或者其他你需要写入的值
if (StringUtils.isEmpty(finalString) || finalString.trim().equals("")) {//判断是空或者是寄存器是零的话就返回
log.info("没有值或者已被清零");
} else {
//如果不是零的话就对寄存器清零
deleteForModbus(registerAddress, registerNum, unitId, connection);
}
WriteMultipleRegistersRequest writeRequest = new WriteMultipleRegistersRequest(registerAddress, writeRegisters);
writeRequest.setUnitID(unitId);
ModbusTCPTransaction writeTransaction = new ModbusTCPTransaction(connection);
writeTransaction.setRequest(writeRequest);
writeTransaction.execute();
log.info("寄存器已清零");
} else {
log.info("处理数据出现异常");
}
@ -308,7 +353,7 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
if (equipmentDataDetails.size() < 80) {
//批量新增
int size = equipmentDataDetails.size();
log.info("直接新增个数: {}" ,size);
log.info("直接新增个数: {}", size);
getInformationForExcelMapper.saveByExcels(equipmentDataDetails);
} else {
@ -338,6 +383,24 @@ public class ModbusCommunicateServiceImpl extends ServiceImpl<ModbusCommunicateM
}
}
}
//数据清零
public void deleteForModbus(int registerAddress, int registerNum, int unitId, TCPMasterConnection connection) {
try {
// 准备写入的寄存器数组
Register[] writeRegisters = new Register[registerNum];
for (int i = 0; i < registerNum; i++) {
writeRegisters[i] = new SimpleRegister(0); // 设置为0或者其他你需要写入的值
}
WriteMultipleRegistersRequest writeRequest = new WriteMultipleRegistersRequest(registerAddress, writeRegisters);
writeRequest.setUnitID(unitId);
ModbusTCPTransaction writeTransaction = new ModbusTCPTransaction(connection);
writeTransaction.setRequest(writeRequest);
writeTransaction.execute();
log.info("寄存器已清零");
} catch (Exception e) {
log.error("连接Modbus设备时出现异常: {}", e.getMessage());
e.printStackTrace();
}
}
}
Loading…
Cancel
Save