1.ndc交互粘包需要分割判断

2.空架入库会出现最后同时满料,增加软锁控制,创建任务时过滤,二次分配时可以放,任务完成或取消后解锁
This commit is contained in:
psh
2024-07-18 13:48:21 +08:00
parent 67c68ae05b
commit 2d1398d801
4 changed files with 117 additions and 30 deletions

View File

@@ -17,6 +17,7 @@ import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.utils.ByteUtil;
import org.nl.system.service.lucene.LuceneExecuteLogService;
import org.nl.system.service.param.ISysParamService;
import org.nl.config.SpringContextHolder;
@@ -28,7 +29,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -112,12 +113,13 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
StringBuffer bs1 = new StringBuffer("0");
bs.append(temp < 16 ? bs1.append(Integer.toHexString(temp)) : Integer.toHexString(temp));
}
int chunkSize = 28;
List<int[]> chunks = this.splitArray(arrAll, chunkSize);
for (int i = 0; i < chunks.size(); i++) {
int[] arr = chunks.get(i);
if (arr[8] * 256 + arr[9] == 0x73) {
List<int[]> packets = ByteUtil.splitAndConvertPackets(bs.toString());
log.info("接收agv上报信息" + bs);
// 打印分割后的报文
for (int i = 0; i < packets.size(); i++) {
int[] arr = packets.get(i);
log.info("处理当前分割部分{}", Arrays.toString(arr));
if (arr.length>10&&arr[8] * 256 + arr[9] == 0x73) {
byte[] data = null;
//执行阶段
int phase = arr[16] * 256 + arr[17];
@@ -247,6 +249,7 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
if (!ObjectUtil.isEmpty(data)) {
write(data);
}
} else {
log.info("agv上报不是0073类型动作不处理");
}
@@ -303,22 +306,5 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
}
}
public static List<int[]> splitArray(int[] array, int chunkSize) {
List<int[]> resultList = new ArrayList<>();
int length = array.length;
for (int i = 0; i < length; i += chunkSize) {
// 计算当前子数组的大小
int currentChunkSize = Math.min(chunkSize, length - i);
// 创建并填充新的子数组
int[] chunk = new int[currentChunkSize];
System.arraycopy(array, i, chunk, 0, currentChunkSize);
resultList.add(chunk);
}
return resultList;
}
}

View File

@@ -0,0 +1,90 @@
package org.nl.acs.utils;
import java.util.ArrayList;
import java.util.List;
public class ByteUtil{
public static List<int[]> splitAndConvertPackets(String data) {
// 将输入的十六进制字符串转换为字节数组
byte[] dataBytes = hexStringToByteArray(data);
// 87CD的字节表示
byte[] startMarker = {(byte) 0x87, (byte) 0xCD};
// 存储结果的列表
List<int[]> packets = new ArrayList<>();
// 当前分割点
int start = 0;
// 遍历整个字节数组
while (start < dataBytes.length) {
// 找到下一个87CD的起始位置
int nextStart = findStartMarker(dataBytes, startMarker, start + 2);
if (nextStart == -1) {
// 没有找到下一个87CD说明到了最后一个包
packets.add(byteArrayToIntArray(dataBytes, start, dataBytes.length - start));
break;
} else {
// 找到一个新的87CD将前面的部分作为一个完整的包
packets.add(byteArrayToIntArray(dataBytes, start, nextStart - start));
start = nextStart;
}
}
return packets;
}
private static int findStartMarker(byte[] data, byte[] marker, int start) {
for (int i = start; i <= data.length - marker.length; i++) {
boolean match = true;
for (int j = 0; j < marker.length; j++) {
if (data[i + j] != marker[j]) {
match = false;
break;
}
}
if (match) {
return i;
}
}
return -1;
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static int[] byteArrayToIntArray(byte[] bytes, int offset, int length) {
int[] intArray = new int[length];
for (int i = 0; i < length; i++) {
intArray[i] = bytes[offset + i] & 0xFF;
}
return intArray;
}
public static void main(String[] args) {
String data = "87cd0008001400010073001000796e030003023e0300000000003f2c87cd00080014000100730010007b6e03000309370200000000003f2d87cd00080014000100730010007f6e03000309310600000000003f3087cd00080014000100730010001f6e030009085c06000001085c3eec87cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f0006000000000000000000030000012e669788c40000708000000000000000000000000400000000000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c50000708000000000000000000000000200000a590000000000000000";
// 处理数据
List<int[]> packets = splitAndConvertPackets(data);
// 打印分割后的报文
for (int i = 0; i < packets.size(); i++) {
System.out.print("Packet " + (i + 1) + ": ");
for (int value : packets.get(i)) {
System.out.print(String.format("%02x", value) + " ");
}
System.out.println();
}
}
}