| | |
| | | import com.zy.core.network.api.ZyStationConnectApi; |
| | | import com.zy.core.network.entity.ZyStationStatusEntity; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | |
| | | import java.util.concurrent.CopyOnWriteArrayList; |
| | |
| | | */ |
| | | public class ZyStationFakeConnect implements ZyStationConnectApi { |
| | | |
| | | private final List<ZyStationStatusEntity> statusList = new CopyOnWriteArrayList<>(); |
| | | private static int LOCK_STATION = 0; |
| | | private final DeviceConfig deviceConfig; |
| | | private HashMap<Integer, List<ZyStationStatusEntity>> deviceStatusMap = new HashMap<>(); |
| | | private HashMap<Integer, DeviceConfig> deviceConfigMap = new HashMap<>(); |
| | | private RedisUtil redisUtil; |
| | | // 允许并行执行多个命令任务(固定线程池)。如需更高并发可调整大小。 |
| | | private final ExecutorService executor = Executors |
| | | .newFixedThreadPool(9999); |
| | | |
| | | public ZyStationFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) { |
| | | this.deviceConfig = deviceConfig; |
| | | public void addFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) { |
| | | this.redisUtil = redisUtil; |
| | | |
| | | if (deviceConfigMap.containsKey(deviceConfig.getDeviceNo())) { |
| | | return; |
| | | } |
| | | deviceConfigMap.put(deviceConfig.getDeviceNo(), deviceConfig); |
| | | deviceStatusMap.put(deviceConfig.getDeviceNo(), new CopyOnWriteArrayList<>()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<ZyStationStatusEntity> getStatus() { |
| | | if (this.statusList.isEmpty()) { |
| | | public List<ZyStationStatusEntity> getStatus(Integer deviceNo) { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | if (statusList == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | DeviceConfig deviceConfig = deviceConfigMap.get(deviceNo); |
| | | if (statusList.isEmpty()) { |
| | | List<ZyStationStatusEntity> init = JSON.parseArray(deviceConfig.getFakeInitStatus(), ZyStationStatusEntity.class); |
| | | if (init != null) { |
| | | statusList.addAll(init); |
| | | for (ZyStationStatusEntity status : this.statusList) { |
| | | for (ZyStationStatusEntity status : statusList) { |
| | | status.setAutoing(true);// 模拟自动运行 |
| | | status.setLoading(false);// 模拟有物 |
| | | status.setInEnable(true);// 模拟可入 |
| | | status.setOutEnable(true);// 模拟可出 |
| | | status.setEmptyMk(false);// 模拟空板信号 |
| | | status.setFullPlt(false);// 模拟满托盘 |
| | | status.setRunBlock(false);// 运行无堵塞 |
| | | status.setPalletHeight(0);// 模拟托盘高度为0 |
| | | status.setError(0);// 模拟无报警 |
| | | status.setBarcode("");// 模拟无条码 |
| | |
| | | } |
| | | } |
| | | |
| | | return this.statusList; |
| | | return statusList; |
| | | } |
| | | |
| | | @Override |
| | | public CommandResponse sendCommand(StationCommand command) { |
| | | public CommandResponse sendCommand(Integer deviceNo, StationCommand command) { |
| | | executor.submit(() -> { |
| | | try { |
| | | handleCommand(command); |
| | | handleCommand(deviceNo, command); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | |
| | | return new CommandResponse(true, "命令已受理(异步执行)"); |
| | | } |
| | | |
| | | private void handleCommand(StationCommand command) { |
| | | private void handleCommand(Integer deviceNo, StationCommand command) { |
| | | News.info("[WCS Debug] 站点仿真模拟已启动,命令数据={}", JSON.toJSONString(command)); |
| | | Integer taskNo = command.getTaskNo(); |
| | | Integer stationId = command.getStationId(); |
| | |
| | | |
| | | if(taskNo == 0 && targetStationId == 0){ |
| | | //清空站点 |
| | | resetStation(stationId); |
| | | resetStation(deviceNo, stationId); |
| | | return; |
| | | } |
| | | |
| | |
| | | |
| | | if (taskNo == 9998 && targetStationId == 0) { |
| | | //生成出库站点仿真数据 |
| | | generateFakeOutStationData(stationId); |
| | | generateFakeOutStationData(deviceNo, stationId); |
| | | return; |
| | | } |
| | | |
| | | if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) { |
| | | //下发任务数据-不允许只是下发数据 |
| | | generateStationData(taskNo, stationId, targetStationId); |
| | | generateStationData(deviceNo, taskNo, stationId, targetStationId); |
| | | } |
| | | |
| | | String startLev = String.valueOf(stationId).substring(0, 1); |
| | |
| | | } |
| | | } |
| | | |
| | | private void generateFakeOutStationData(Integer stationId) { |
| | | private void generateFakeOutStationData(Integer deviceNo, Integer stationId) { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | ZyStationStatusEntity status = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); |
| | | if (status == null) { |
| | |
| | | } |
| | | } |
| | | |
| | | private void generateStationData(Integer taskNo, Integer stationId, Integer targetStationId) { |
| | | private void generateStationData(Integer deviceNo, Integer taskNo, Integer stationId, Integer targetStationId) { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | ZyStationStatusEntity status = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); |
| | | if (status == null) { |
| | |
| | | } |
| | | } |
| | | |
| | | private void resetStation(Integer stationId) { |
| | | private void resetStation(Integer deviceNo, Integer stationId) { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | ZyStationStatusEntity status = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null); |
| | | if (status == null) { |
| | |
| | | return; |
| | | } |
| | | |
| | | stationMove(navigateNodes, taskNo, stationId, true, generateBarcode); |
| | | stationMove(targetNavigateNodes, taskNo, targetStationId, false, generateBarcode); |
| | | boolean result = stationMove(navigateNodes, taskNo, stationId, true, generateBarcode); |
| | | if(result) { |
| | | stationMove(targetNavigateNodes, taskNo, targetStationId, false, generateBarcode); |
| | | } |
| | | } |
| | | |
| | | private void stationMove(List<NavigateNode> navigateNodes, Integer taskNo, Integer targetStationId, boolean clearData, boolean generateBarcode) { |
| | | private boolean stationMove(List<NavigateNode> navigateNodes, Integer taskNo, Integer targetStationId, boolean clearData, boolean generateBarcode) { |
| | | Integer lastStationId = null; |
| | | Integer targetStationDeviceNo = null; |
| | | |
| | | long executeTime = System.currentTimeMillis(); |
| | | int i = 0; |
| | | while (i < navigateNodes.size()) { |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return false; |
| | | } |
| | | NavigateNode navigateNode = navigateNodes.get(i); |
| | | JSONObject valueObject = JSON.parseObject(navigateNode.getNodeValue()); |
| | | Integer currentStationId = valueObject.getInteger("stationId"); |
| | | Integer currentStationDeviceNo = valueObject.getInteger("deviceNo"); |
| | | if (currentStationId.equals(targetStationId)) { |
| | | targetStationDeviceNo = currentStationDeviceNo; |
| | | } |
| | | |
| | | Integer nextStationId = null; |
| | | Integer nextStationDeviceNo = null; |
| | | try { |
| | | NavigateNode nextNode = navigateNodes.get(i + 1); |
| | | JSONObject nextValueObject = JSON.parseObject(nextNode.getNodeValue()); |
| | | nextStationId = nextValueObject.getInteger("stationId"); |
| | | nextStationDeviceNo = nextValueObject.getInteger("deviceNo"); |
| | | } catch (Exception e) { |
| | | |
| | | } |
| | | |
| | | if (nextStationId != null) { |
| | | if (!checkTaskNoInArea(taskNo)) { |
| | | boolean fakeAllowCheckBlock = true; |
| | | Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); |
| | | if (systemConfigMapObj != null) { |
| | | HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj; |
| | | if (!systemConfigMap.get("fakeAllowCheckBlock").equals("Y")) { |
| | | fakeAllowCheckBlock = false; |
| | | } |
| | | } |
| | | |
| | | if (fakeAllowCheckBlock && System.currentTimeMillis() - executeTime > 1000 * 10) { |
| | | //认定堵塞 |
| | | boolean result = runBlockStation(taskNo, currentStationId, currentStationDeviceNo, taskNo, currentStationId); |
| | | if(!result) { |
| | | continue; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (i == 0) { |
| | | boolean result = initStationMove(taskNo, currentStationId, taskNo, targetStationId, true, null); |
| | | boolean result = initStationMove(taskNo, currentStationId, currentStationDeviceNo, taskNo, targetStationId, true, null); |
| | | if (!result) { |
| | | continue; |
| | | } |
| | | sleep(1000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if(nextStationId != null) { |
| | | boolean result = stationMoveToNext(taskNo, currentStationId, nextStationId, taskNo, targetStationId); |
| | | boolean result = stationMoveToNext(taskNo, currentStationId, currentStationDeviceNo, nextStationId, nextStationDeviceNo, taskNo, targetStationId); |
| | | if (!result) { |
| | | continue; |
| | | } |
| | |
| | | } |
| | | |
| | | i++; |
| | | executeTime = System.currentTimeMillis(); |
| | | sleep(1000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (generateBarcode) { |
| | | if (lastStationId != null) { |
| | | while (true) { |
| | | boolean result = generateStationBarcode(taskNo, targetStationId); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | break; |
| | | } |
| | | boolean result = generateStationBarcode(taskNo, targetStationId, targetStationDeviceNo); |
| | | sleep(1000); |
| | | if (!result) { |
| | | continue; |
| | |
| | | |
| | | if (clearData) { |
| | | sleep(10000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return true; |
| | | } |
| | | if (lastStationId != null) { |
| | | while (true) { |
| | | boolean result = clearStation(taskNo, targetStationId); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | break; |
| | | } |
| | | boolean result = clearStation(taskNo, targetStationId, targetStationDeviceNo); |
| | | sleep(1000); |
| | | if (!result) { |
| | | continue; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | private void sleep(long ms) { |
| | | try { |
| | | Thread.sleep(ms); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | Thread.currentThread().interrupt(); |
| | | } |
| | | } |
| | | |
| | |
| | | return true; |
| | | } |
| | | |
| | | public synchronized boolean updateStationData(Integer lockTaskNo, Integer stationId, Integer taskNo, Integer targetStaNo, Boolean isLoading, String barcode) { |
| | | public synchronized boolean updateStationData(Integer lockTaskNo, Integer stationId, Integer deviceNo, Integer taskNo, Integer targetStaNo, Boolean isLoading, String barcode, Boolean runBlock) { |
| | | if (LOCK_STATION != lockTaskNo) { |
| | | return false; |
| | | } |
| | | |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | if (barcode != null) { |
| | | currentStatus.setBarcode(barcode); |
| | | } |
| | | |
| | | if (runBlock != null) { |
| | | currentStatus.setRunBlock(runBlock); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public synchronized boolean initStationMove(Integer lockTaskNo, Integer currentStationId, Integer taskNo, Integer targetStationId, Boolean isLoading, String barcode) { |
| | | public synchronized boolean initStationMove(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo, Integer taskNo, Integer targetStationId, Boolean isLoading, String barcode) { |
| | | boolean executeResult = lockExecute(lockTaskNo, () -> { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | ZyStationStatusEntity currentStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | .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) { |
| | | if (!currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (currentStatus.getTaskNo() > 0 || currentStatus.isLoading()) { |
| | | return false; |
| | | } |
| | | |
| | | boolean result = updateStationData(taskNo, currentStationId, taskNo, targetStationId, isLoading, barcode); |
| | | boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, taskNo, targetStationId, isLoading, barcode, false); |
| | | if (!result) { |
| | | return false; |
| | | } |
| | |
| | | return executeResult; |
| | | } |
| | | |
| | | public synchronized boolean stationMoveToNext(Integer lockTaskNo, Integer currentStationId, Integer nextStationId, Integer taskNo, Integer targetStaNo) { |
| | | public synchronized boolean stationMoveToNext(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo, Integer nextStationId, Integer nextStationDeviceNo, Integer taskNo, Integer targetStaNo) { |
| | | boolean executeResult = lockExecute(lockTaskNo, () -> { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | List<ZyStationStatusEntity> nextStatusList = deviceStatusMap.get(nextStationDeviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | ZyStationStatusEntity currentStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | |
| | | ZyStationStatusEntity nextStatus = statusList.stream() |
| | | ZyStationStatusEntity nextStatus = nextStatusList.stream() |
| | | .filter(item -> item.getStationId().equals(nextStationId)).findFirst().orElse(null); |
| | | |
| | | if (currentStatus == null || nextStatus == null) { |
| | |
| | | return false; |
| | | } |
| | | |
| | | boolean result = updateStationData(lockTaskNo, nextStationId, taskNo, targetStaNo, true, null); |
| | | boolean result = updateStationData(lockTaskNo, nextStationId, nextStationDeviceNo, taskNo, targetStaNo, true, null, false); |
| | | if (!result) { |
| | | return false; |
| | | } |
| | | |
| | | boolean result2 = updateStationData(lockTaskNo, currentStationId, 0, 0, false, null); |
| | | boolean result2 = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, 0, 0, false, "", false); |
| | | if (!result2) { |
| | | return false; |
| | | } |
| | |
| | | return executeResult; |
| | | } |
| | | |
| | | public synchronized boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId) { |
| | | public synchronized boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo) { |
| | | boolean executeResult = lockExecute(lockTaskNo, () -> { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | ZyStationStatusEntity currentStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | |
| | |
| | | String barcodeTime = String.valueOf(System.currentTimeMillis()); |
| | | String barcode = barcodeTime.substring(5); |
| | | |
| | | boolean result = updateStationData(lockTaskNo, currentStationId, null, null, null, barcode); |
| | | boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, null, null, null, barcode, null); |
| | | if (!result) { |
| | | return false; |
| | | } |
| | |
| | | return executeResult; |
| | | } |
| | | |
| | | public synchronized boolean clearStation(Integer lockTaskNo, Integer currentStationId) { |
| | | public synchronized boolean clearStation(Integer deviceNo, Integer lockTaskNo, Integer currentStationId) { |
| | | boolean executeResult = lockExecute(lockTaskNo, () -> { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | ZyStationStatusEntity currentStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | |
| | |
| | | return false; |
| | | } |
| | | |
| | | boolean result = updateStationData(lockTaskNo, currentStationId, 0, 0, false, ""); |
| | | boolean result = updateStationData(deviceNo, lockTaskNo, currentStationId, 0, 0, false, "", false); |
| | | if (!result) { |
| | | return false; |
| | | } |
| | | return true; |
| | | }); |
| | | |
| | | return executeResult; |
| | | } |
| | | |
| | | public synchronized boolean runBlockStation(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo, Integer taskNo, Integer blockStationId) { |
| | | boolean executeResult = lockExecute(lockTaskNo, () -> { |
| | | List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo); |
| | | if (statusList == null) { |
| | | return false; |
| | | } |
| | | |
| | | ZyStationStatusEntity currentStatus = statusList.stream() |
| | | .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null); |
| | | |
| | | if (currentStatus == null) { |
| | | return false; |
| | | } |
| | | |
| | | boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, taskNo, blockStationId, true, "", true); |
| | | if (!result) { |
| | | return false; |
| | | } |