1.ndc交互粘包需要分割判断
2.空架入库会出现最后同时满料,增加软锁控制,创建任务时过滤,二次分配时可以放,任务完成或取消后解锁
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user