| | |
| | | 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.ArrayList; |
| | | 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 List<ZyStationStatusEntity> statusList = new ArrayList<>(); |
| | | private final List<ZyStationStatusEntity> 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) { |
| | | public ZyStationFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) { |
| | | this.deviceConfig = deviceConfig; |
| | | this.redisUtil = redisUtil; |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public List<ZyStationStatusEntity> getStatus() { |
| | | if (this.statusList.isEmpty()) { |
| | | this.statusList = JSON.parseArray(deviceConfig.getFakeInitStatus(), ZyStationStatusEntity.class); |
| | | |
| | | 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("");// 模拟无条码 |
| | | List<ZyStationStatusEntity> 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("");// 模拟无条码 |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | Integer taskNo = command.getTaskNo(); |
| | | Integer stationId = command.getStationId(); |
| | | Integer targetStationId = command.getTargetStaNo(); |
| | | boolean generateBarcode = false; |
| | | |
| | | if(taskNo == 0 && targetStationId == 0){ |
| | | //清空站点 |
| | |
| | | return; |
| | | } |
| | | |
| | | if (taskNo == 9999 && targetStationId == 0) { |
| | | //任务号属于仿真入库任务号 |
| | | if (checkTaskNoInArea(taskNo)) { |
| | | //生成仿真数据 |
| | | generateFakeData(stationId, taskNo); |
| | | return; |
| | | generateBarcode = true; |
| | | } |
| | | |
| | | if (taskNo == 9998 && targetStationId == 0) { |
| | |
| | | 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); |
| | | currentLevCommand(command, generateBarcode); |
| | | }else { |
| | | diffLevCommand(command); |
| | | diffLevCommand(command, generateBarcode); |
| | | } |
| | | } |
| | | |
| | | private void generateFakeData(Integer stationId, Integer taskNo) { |
| | | ZyStationStatusEntity status = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); |
| | | if (status == null) { |
| | | return; |
| | | } |
| | | |
| | | String barcodeTime = String.valueOf(System.currentTimeMillis()); |
| | | String barcode = barcodeTime.substring(5); |
| | | |
| | | status.setTaskNo(taskNo); |
| | | status.setLoading(true); |
| | | status.setBarcode(barcode); |
| | | } |
| | | |
| | | private void generateFakeOutStationData(Integer stationId) { |
| | |
| | | return; |
| | | } |
| | | |
| | | status.setLoading(true); |
| | | 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) { |
| | |
| | | return; |
| | | } |
| | | |
| | | status.setTaskNo(0); |
| | | status.setLoading(false); |
| | | status.setBarcode(""); |
| | | synchronized (status) { |
| | | status.setTaskNo(0); |
| | | status.setLoading(false); |
| | | status.setBarcode(""); |
| | | } |
| | | } |
| | | |
| | | private void currentLevCommand(StationCommand command) { |
| | | private void currentLevCommand(StationCommand command, boolean generateBarcode) { |
| | | NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); |
| | | if (navigateUtils == null) { |
| | | return; |
| | |
| | | return; |
| | | } |
| | | |
| | | stationMove(navigateNodes, taskNo, targetStationId, false); |
| | | stationMove(navigateNodes, taskNo, targetStationId, false, generateBarcode); |
| | | } |
| | | |
| | | private void diffLevCommand(StationCommand command) { |
| | | private void diffLevCommand(StationCommand command, boolean generateBarcode) { |
| | | NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); |
| | | if (navigateUtils == null) { |
| | | return; |
| | |
| | | return; |
| | | } |
| | | |
| | | stationMove(navigateNodes, taskNo, stationId, true); |
| | | stationMove(targetNavigateNodes, taskNo, targetStationId, false); |
| | | stationMove(navigateNodes, taskNo, stationId, true, generateBarcode); |
| | | stationMove(targetNavigateNodes, taskNo, targetStationId, false, generateBarcode); |
| | | } |
| | | |
| | | private void stationMove(List<NavigateNode> navigateNodes, Integer taskNo, Integer targetStationId, boolean clearData) { |
| | | private void stationMove(List<NavigateNode> navigateNodes, Integer taskNo, Integer targetStationId, boolean clearData, boolean generateBarcode) { |
| | | Integer lastStationId = null; |
| | | for (int i = 0; i < navigateNodes.size(); i++) { |
| | | |
| | | int i = 0; |
| | | while (i < navigateNodes.size()) { |
| | | NavigateNode navigateNode = navigateNodes.get(i); |
| | | JSONObject valueObject = JSON.parseObject(navigateNode.getNodeValue()); |
| | | Integer currentStationId = valueObject.getInteger("stationId"); |
| | | ZyStationStatusEntity status = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | if (status == null) { |
| | | continue; |
| | | |
| | | Integer nextStationId = null; |
| | | try { |
| | | NavigateNode nextNode = navigateNodes.get(i + 1); |
| | | JSONObject nextValueObject = JSON.parseObject(nextNode.getNodeValue()); |
| | | nextStationId = nextValueObject.getInteger("stationId"); |
| | | } catch (Exception e) { |
| | | |
| | | } |
| | | |
| | | try { |
| | | while (!Thread.currentThread().isInterrupted()) { |
| | | ZyStationStatusEntity nextStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | if (nextStatus == null) { |
| | | 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; |
| | | } |
| | | |
| | | if (nextStatus.getTaskNo() == 0 || nextStatus.getTaskNo() == 9999) { |
| | | break; |
| | | } |
| | | |
| | | sleep(100); |
| | | } |
| | | } catch (Exception e) { |
| | | continue; |
| | | } |
| | | |
| | | if (lastStationId != null) { |
| | | Integer finalLastStationId = lastStationId; |
| | | ZyStationStatusEntity lastStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(finalLastStationId)).findFirst().orElse(null); |
| | | if (lastStatus != null) { |
| | | synchronized (lastStatus) { |
| | | lastStatus.setTaskNo(0); |
| | | lastStatus.setTargetStaNo(0); |
| | | lastStatus.setLoading(false); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | synchronized (status) { |
| | | status.setTaskNo(taskNo); |
| | | status.setTargetStaNo(targetStationId); |
| | | status.setLoading(true); |
| | | } |
| | | |
| | | lastStationId = currentStationId; |
| | | sleep(1000); |
| | | } |
| | | |
| | | if (clearData) { |
| | | sleep(10000); |
| | | if (lastStationId != null) { |
| | | Integer finalLastStationId = lastStationId; |
| | | ZyStationStatusEntity lastStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(finalLastStationId)).findFirst().orElse(null); |
| | | if (lastStatus != null) { |
| | | synchronized (lastStatus) { |
| | | lastStatus.setTaskNo(0); |
| | | lastStatus.setTargetStaNo(0); |
| | | lastStatus.setLoading(false); |
| | | while (true) { |
| | | boolean result = clearStation(taskNo, targetStationId); |
| | | sleep(1000); |
| | | if (!result) { |
| | | continue; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | |
| | | 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<Boolean> 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; |
| | | } |
| | | } |