package com.zy.core.network.fake; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.core.common.SpringUtils; import com.zy.asrs.entity.DeviceConfig; import com.zy.common.model.NavigateNode; import com.zy.common.utils.NavigateUtils; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.enums.RedisKeyType; import com.zy.core.model.CommandResponse; import com.zy.core.model.command.StationCommand; import com.zy.core.network.api.ZyStationConnectApi; import com.zy.core.network.entity.ZyStationStatusEntity; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Supplier; /** * 输送站假连接(模拟) */ public class ZyStationFakeConnect implements ZyStationConnectApi { private final List statusList = new CopyOnWriteArrayList<>(); private static int LOCK_STATION = 0; private final DeviceConfig deviceConfig; private RedisUtil redisUtil; // 允许并行执行多个命令任务(固定线程池)。如需更高并发可调整大小。 private final ExecutorService executor = Executors .newFixedThreadPool(9999); public ZyStationFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) { this.deviceConfig = deviceConfig; this.redisUtil = redisUtil; } @Override public boolean connect() { return true; } @Override public boolean disconnect() { executor.shutdownNow(); return true; } @Override public List getStatus() { if (this.statusList.isEmpty()) { List init = JSON.parseArray(deviceConfig.getFakeInitStatus(), ZyStationStatusEntity.class); if (init != null) { statusList.addAll(init); for (ZyStationStatusEntity status : this.statusList) { status.setAutoing(true);// 模拟自动运行 status.setLoading(false);// 模拟有物 status.setInEnable(true);// 模拟可入 status.setOutEnable(true);// 模拟可出 status.setEmptyMk(false);// 模拟空板信号 status.setFullPlt(false);// 模拟满托盘 status.setPalletHeight(0);// 模拟托盘高度为0 status.setError(0);// 模拟无报警 status.setBarcode("");// 模拟无条码 } } } return this.statusList; } @Override public CommandResponse sendCommand(StationCommand command) { executor.submit(() -> { try { handleCommand(command); } catch (Exception e) { e.printStackTrace(); } }); return new CommandResponse(true, "命令已受理(异步执行)"); } private void handleCommand(StationCommand command) { News.info("[WCS Debug] 站点仿真模拟已启动,命令数据={}", JSON.toJSONString(command)); Integer taskNo = command.getTaskNo(); Integer stationId = command.getStationId(); Integer targetStationId = command.getTargetStaNo(); boolean generateBarcode = false; if(taskNo == 0 && targetStationId == 0){ //清空站点 resetStation(stationId); return; } //任务号属于仿真入库任务号 if (checkTaskNoInArea(taskNo)) { //生成仿真数据 generateBarcode = true; } if (taskNo == 9998 && targetStationId == 0) { //生成出库站点仿真数据 generateFakeOutStationData(stationId); return; } if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) { //下发任务数据-不允许只是下发数据 generateStationData(taskNo, stationId, targetStationId); } String startLev = String.valueOf(stationId).substring(0, 1); String endLev = String.valueOf(targetStationId).substring(0, 1); if (startLev.equals(endLev)) { currentLevCommand(command, generateBarcode); }else { diffLevCommand(command, generateBarcode); } } private void generateFakeOutStationData(Integer stationId) { ZyStationStatusEntity status = statusList.stream() .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); if (status == null) { return; } synchronized (status) { status.setLoading(true); } } private void generateStationData(Integer taskNo, Integer stationId, Integer targetStationId) { ZyStationStatusEntity status = statusList.stream() .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); if (status == null) { return; } synchronized (status) { status.setTaskNo(taskNo); status.setTargetStaNo(targetStationId); } } private void resetStation(Integer stationId) { ZyStationStatusEntity status = statusList.stream() .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); if (status == null) { return; } synchronized (status) { status.setTaskNo(0); status.setLoading(false); status.setBarcode(""); } } private void currentLevCommand(StationCommand command, boolean generateBarcode) { NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); if (navigateUtils == null) { return; } Integer taskNo = command.getTaskNo(); Integer stationId = command.getStationId(); Integer targetStationId = command.getTargetStaNo(); String startLev = String.valueOf(stationId).substring(0, 1); List navigateNodes = null; try { navigateNodes = navigateUtils.calcByStationId(Integer.parseInt(startLev), stationId, targetStationId); } catch (Exception e) { e.printStackTrace(); } if (navigateNodes == null) { return; } stationMove(navigateNodes, taskNo, targetStationId, false, generateBarcode); } private void diffLevCommand(StationCommand command, boolean generateBarcode) { NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); if (navigateUtils == null) { return; } Integer taskNo = command.getTaskNo(); Integer stationId = command.getStationId(); Integer targetStationId = command.getTargetStaNo(); String startLev = String.valueOf(stationId).substring(0, 1); String endLev = String.valueOf(targetStationId).substring(0, 1); List navigateNodes = null; List targetNavigateNodes = null; try { List liftStationList = navigateUtils.findLiftStationList(Integer.parseInt(startLev)); if(liftStationList.isEmpty()){ //未找到提升机节点 return; } List targetLiftStationList = navigateUtils.findLiftStationList(Integer.parseInt(endLev)); if(targetLiftStationList.isEmpty()){ //未找到提升机节点 return; } for (NavigateNode liftStation : liftStationList) { JSONObject valuObject = JSON.parseObject(liftStation.getNodeValue()); if(valuObject == null){ continue; } Integer liftStationId = valuObject.getInteger("stationId"); Integer liftNo = valuObject.getInteger("liftNo"); Integer targetLiftStationId = null; for (NavigateNode targetLiftStation : targetLiftStationList) { JSONObject targetValuObject = JSON.parseObject(targetLiftStation.getNodeValue()); if(targetValuObject == null){ continue; } Integer targetLiftNo = targetValuObject.getInteger("liftNo"); if(liftNo.equals(targetLiftNo)){ targetLiftStationId = targetValuObject.getInteger("stationId"); break; } } if(targetLiftStationId == null){ continue; } navigateNodes = navigateUtils.calcByStationId(Integer.parseInt(startLev), stationId, liftStationId); if(navigateNodes == null){ continue; } //计算提升机到目标站的路径 targetNavigateNodes = navigateUtils.calcByStationId(Integer.parseInt(endLev), targetLiftStationId, targetStationId); if(targetNavigateNodes == null) { continue; } } } catch (Exception e) { e.printStackTrace(); } if (navigateNodes == null || targetNavigateNodes == null) { return; } stationMove(navigateNodes, taskNo, stationId, true, generateBarcode); stationMove(targetNavigateNodes, taskNo, targetStationId, false, generateBarcode); } private void stationMove(List navigateNodes, Integer taskNo, Integer targetStationId, boolean clearData, boolean generateBarcode) { Integer lastStationId = null; int i = 0; while (i < navigateNodes.size()) { NavigateNode navigateNode = navigateNodes.get(i); JSONObject valueObject = JSON.parseObject(navigateNode.getNodeValue()); Integer currentStationId = valueObject.getInteger("stationId"); Integer nextStationId = null; try { NavigateNode nextNode = navigateNodes.get(i + 1); JSONObject nextValueObject = JSON.parseObject(nextNode.getNodeValue()); nextStationId = nextValueObject.getInteger("stationId"); } catch (Exception e) { } if (nextStationId != null) { } if (i == 0) { boolean result = initStationMove(taskNo, currentStationId, taskNo, targetStationId, true, null); if (!result) { continue; } sleep(1000); } if(nextStationId != null) { boolean result = stationMoveToNext(taskNo, currentStationId, nextStationId, taskNo, targetStationId); if (!result) { continue; } lastStationId = currentStationId; } i++; sleep(1000); } if (generateBarcode) { if (lastStationId != null) { while (true) { boolean result = generateStationBarcode(taskNo, targetStationId); sleep(1000); if (!result) { continue; } break; } } } if (clearData) { sleep(10000); if (lastStationId != null) { while (true) { boolean result = clearStation(taskNo, targetStationId); sleep(1000); if (!result) { continue; } break; } } } } private void sleep(long ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized boolean setLockStation(Integer uuid) { if (LOCK_STATION == 0) { LOCK_STATION = uuid; return true; }else { if(LOCK_STATION == uuid) { return true; } } return false; } public synchronized boolean releaseLockStation(Integer uuid) { if (LOCK_STATION != uuid) { return false; } LOCK_STATION = 0; return true; } public synchronized boolean updateStationData(Integer lockTaskNo, Integer stationId, Integer taskNo, Integer targetStaNo, Boolean isLoading, String barcode) { if (LOCK_STATION != lockTaskNo) { return false; } ZyStationStatusEntity currentStatus = statusList.stream() .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); if (currentStatus == null) { return false; } if (taskNo != null) { currentStatus.setTaskNo(taskNo); } if (targetStaNo != null) { currentStatus.setTargetStaNo(targetStaNo); } if (isLoading != null) { currentStatus.setLoading(isLoading); } if (barcode != null) { currentStatus.setBarcode(barcode); } return true; } public synchronized boolean initStationMove(Integer lockTaskNo, Integer currentStationId, Integer taskNo, Integer targetStationId, Boolean isLoading, String barcode) { boolean executeResult = lockExecute(lockTaskNo, () -> { ZyStationStatusEntity currentStatus = statusList.stream() .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); if (currentStatus == null) { return false; } if(currentStatus.getTaskNo().equals(taskNo)) { return true; } if (currentStatus.getTaskNo() > 0 || currentStatus.isLoading()) { return false; } boolean result = updateStationData(taskNo, currentStationId, taskNo, targetStationId, isLoading, barcode); if (!result) { return false; } return true; }); return executeResult; } public synchronized boolean stationMoveToNext(Integer lockTaskNo, Integer currentStationId, Integer nextStationId, Integer taskNo, Integer targetStaNo) { boolean executeResult = lockExecute(lockTaskNo, () -> { ZyStationStatusEntity currentStatus = statusList.stream() .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); ZyStationStatusEntity nextStatus = statusList.stream() .filter(item -> item.getStationId().equals(nextStationId)).findFirst().orElse(null); if (currentStatus == null || nextStatus == null) { return false; } if (nextStatus.getTaskNo() > 0 || nextStatus.isLoading()) { return false; } boolean result = updateStationData(lockTaskNo, nextStationId, taskNo, targetStaNo, true, null); if (!result) { return false; } boolean result2 = updateStationData(lockTaskNo, currentStationId, 0, 0, false, null); if (!result2) { return false; } return true; }); return executeResult; } public synchronized boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId) { boolean executeResult = lockExecute(lockTaskNo, () -> { ZyStationStatusEntity currentStatus = statusList.stream() .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); if (currentStatus == null) { return false; } String barcodeTime = String.valueOf(System.currentTimeMillis()); String barcode = barcodeTime.substring(5); boolean result = updateStationData(lockTaskNo, currentStationId, null, null, null, barcode); if (!result) { return false; } return true; }); return executeResult; } public synchronized boolean clearStation(Integer lockTaskNo, Integer currentStationId) { boolean executeResult = lockExecute(lockTaskNo, () -> { ZyStationStatusEntity currentStatus = statusList.stream() .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); if (currentStatus == null) { return false; } boolean result = updateStationData(lockTaskNo, currentStationId, 0, 0, false, ""); if (!result) { return false; } return true; }); return executeResult; } public synchronized boolean lockExecute(Integer taskNo, Supplier function) { if (!setLockStation(taskNo)) { return false; } boolean result = function.get(); releaseLockStation(taskNo); return result; } private synchronized boolean checkTaskNoInArea(Integer taskNo) { Object fakeTaskNoAreaObj = redisUtil.get(RedisKeyType.FAKE_TASK_NO_AREA.key); if (fakeTaskNoAreaObj == null) { return false; } JSONObject data = JSON.parseObject(String.valueOf(fakeTaskNoAreaObj)); Integer start = data.getInteger("start"); Integer end = data.getInteger("end"); if(taskNo >= start && taskNo <= end) { return true; } return false; } }