From 6c8ee211ae63de5f4ce0bd13b9c34f0524cd656f Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 06 五月 2026 19:11:49 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java |  167 ++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 139 insertions(+), 28 deletions(-)

diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
index 92cadb7..81d4c8d 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
@@ -3,7 +3,8 @@
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.core.common.Cools;
 import com.core.common.DateUtils;
 import com.core.common.SpringUtils;
 import com.zy.asrs.entity.BasDevp;
@@ -29,6 +30,9 @@
 import com.zy.core.network.DeviceConnectPool;
 import com.zy.core.network.ZyStationConnectDriver;
 import com.zy.core.network.entity.ZyStationStatusEntity;
+import com.zy.core.task.DeviceAsyncLogPublisher;
+import com.zy.core.thread.support.RecentStationArrivalTracker;
+import com.zy.core.thread.support.StationErrLogSupport;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 
@@ -38,6 +42,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -46,16 +51,21 @@
 public class ZyStationV3Thread implements Runnable, com.zy.core.thread.StationThread {
 
     private List<StationProtocol> statusList = new ArrayList<>();
+    private volatile List<Integer> taskNoList = new ArrayList<>();
     private DeviceConfig deviceConfig;
     private RedisUtil redisUtil;
     private ZyStationConnectDriver zyStationConnectDriver;
     private int deviceLogCollectTime = 200;
     private long deviceDataLogTime = System.currentTimeMillis();
     private ExecutorService executor = Executors.newFixedThreadPool(9999);
+    private final RecentStationArrivalTracker recentArrivalTracker;
+    private final DeviceAsyncLogPublisher devpAsyncLogPublisher;
 
     public ZyStationV3Thread(DeviceConfig deviceConfig, RedisUtil redisUtil) {
         this.deviceConfig = deviceConfig;
         this.redisUtil = redisUtil;
+        this.recentArrivalTracker = new RecentStationArrivalTracker(redisUtil);
+        this.devpAsyncLogPublisher = SpringUtils.getBean(DeviceAsyncLogPublisher.class);
     }
 
     @Override
@@ -114,7 +124,7 @@
             }
 
             BasDevp basDevp = basDevpService
-                    .selectOne(new EntityWrapper<BasDevp>().eq("devp_no", deviceConfig.getDeviceNo()));
+                    .getOne(new QueryWrapper<BasDevp>().eq("devp_no", deviceConfig.getDeviceNo()));
             if (basDevp == null) {
                 return;
             }
@@ -128,6 +138,7 @@
         }
 
         List<ZyStationStatusEntity> zyStationStatusEntities = zyStationConnectDriver.getStatus();
+        LinkedHashSet<Integer> taskNoSet = new LinkedHashSet<>();
         for (ZyStationStatusEntity statusEntity : zyStationStatusEntities) {
             for (StationProtocol stationProtocol : statusList) {
                 if (stationProtocol.getStationId().equals(statusEntity.getStationId())) {
@@ -146,23 +157,61 @@
                     stationProtocol.setRunBlock(statusEntity.isRunBlock());
                     stationProtocol.setEnableIn(statusEntity.isEnableIn());
                     stationProtocol.setWeight(statusEntity.getWeight());
+                    if (statusEntity.getTaskNo() != null && statusEntity.getTaskNo() > 0) {
+                        taskNoSet.add(statusEntity.getTaskNo());
+                    }
+                    recentArrivalTracker.observe(statusEntity.getStationId(), statusEntity.getTaskNo(), statusEntity.isLoading());
+                }
+
+                if (!Cools.isEmpty(stationProtocol.getSystemWarning())) {
+                    if (stationProtocol.isAutoing()
+                            && !stationProtocol.isLoading()
+                            && redisUtil.get(RedisKeyType.GENERATE_STATION_BACK_LIMIT.key + stationProtocol.getStationId()) == null
+                    ) {
+                        stationProtocol.setSystemWarning("");
+                    }
                 }
             }
         }
+        taskNoList = new ArrayList<>(taskNoSet);
 
         OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆慬id:{1}] <<<<< 瀹炴椂鏁版嵁鏇存柊鎴愬姛", DateUtils.convert(new Date()), deviceConfig.getDeviceNo()));
+        StationErrLogSupport.sync(deviceConfig, redisUtil, statusList);
 
         if (System.currentTimeMillis() - deviceDataLogTime > deviceLogCollectTime) {
-            DeviceDataLog deviceDataLog = new DeviceDataLog();
-            deviceDataLog.setOriginData(JSON.toJSONString(zyStationStatusEntities));
-            deviceDataLog.setWcsData(JSON.toJSONString(statusList));
-            deviceDataLog.setType(String.valueOf(SlaveType.Devp));
-            deviceDataLog.setDeviceNo(deviceConfig.getDeviceNo());
-            deviceDataLog.setCreateTime(new Date());
-
-            redisUtil.set(RedisKeyType.DEVICE_LOG_KEY.key + System.currentTimeMillis(), deviceDataLog, 60 * 60 * 24);
+            Date createTime = new Date();
+            HashMap<Integer, ZyStationStatusEntity> originDataMap = buildStationStatusMap(zyStationStatusEntities);
+            for (int i = 0; i < statusList.size(); i++) {
+                StationProtocol stationProtocol = statusList.get(i);
+                if (stationProtocol == null || stationProtocol.getStationId() == null) {
+                    continue;
+                }
+                DeviceDataLog deviceDataLog = new DeviceDataLog();
+                ZyStationStatusEntity originEntity = originDataMap.get(stationProtocol.getStationId());
+                deviceDataLog.setOriginData(originEntity == null ? null : JSON.toJSONString(originEntity));
+                deviceDataLog.setWcsData(JSON.toJSONString(stationProtocol));
+                deviceDataLog.setType(String.valueOf(SlaveType.Devp));
+                deviceDataLog.setDeviceNo(deviceConfig.getDeviceNo());
+                deviceDataLog.setStationId(stationProtocol.getStationId());
+                deviceDataLog.setCreateTime(createTime);
+                devpAsyncLogPublisher.publishLatest(deviceDataLog);
+            }
             deviceDataLogTime = System.currentTimeMillis();
         }
+    }
+
+    private HashMap<Integer, ZyStationStatusEntity> buildStationStatusMap(List<ZyStationStatusEntity> zyStationStatusEntities) {
+        HashMap<Integer, ZyStationStatusEntity> map = new HashMap<>();
+        if (zyStationStatusEntities == null) {
+            return map;
+        }
+        for (ZyStationStatusEntity statusEntity : zyStationStatusEntities) {
+            if (statusEntity == null || statusEntity.getStationId() == null) {
+                continue;
+            }
+            map.put(statusEntity.getStationId(), statusEntity);
+        }
+        return map;
     }
 
     @Override
@@ -198,7 +247,27 @@
     }
 
     @Override
+    public List<Integer> getAllTaskNoList() {
+        return taskNoList;
+    }
+
+    @Override
+    public boolean hasRecentArrival(Integer stationId, Integer taskNo) {
+        return recentArrivalTracker.hasRecentArrival(stationId, taskNo);
+    }
+
+    @Override
     public StationCommand getCommand(StationCommandType commandType, Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize) {
+        return getCommand(commandType, taskNo, stationId, targetStationId, palletSize, null);
+    }
+
+    @Override
+    public StationCommand getCommand(StationCommandType commandType,
+                                     Integer taskNo,
+                                     Integer stationId,
+                                     Integer targetStationId,
+                                     Integer palletSize,
+                                     Double pathLenFactor) {
         StationCommand stationCommand = new StationCommand();
         stationCommand.setTaskNo(taskNo);
         stationCommand.setStationId(stationId);
@@ -208,7 +277,12 @@
 
         if (commandType == StationCommandType.MOVE) {
             if (!stationId.equals(targetStationId)) {
-                List<Integer> path = calcPathStationIds(stationId, targetStationId);
+                List<Integer> path = calcPathStationIds(taskNo, stationId, targetStationId, pathLenFactor);
+                if (path == null || path.isEmpty()) {
+                    log.warn("杈撻�佺嚎鍛戒护鐢熸垚澶辫触锛岃矾寰勪负绌猴紝taskNo={}, stationId={}, targetStationId={}",
+                            taskNo, stationId, targetStationId);
+                    return null;
+                }
                 stationCommand.setNavigatePath(path);
             }
         }
@@ -250,7 +324,7 @@
                     JSON.toJSONString(commandResponse)
             );
             if (optService != null) {
-                optService.insert(basStationOpt);
+                optService.save(basStationOpt);
             }
         }
         return commandResponse;
@@ -266,12 +340,15 @@
         return zyStationConnectDriver.readOriginCommand(address, length);
     }
 
-    private List<Integer> calcPathStationIds(Integer startStationId, Integer targetStationId) {
+    private List<Integer> calcPathStationIds(Integer taskNo,
+                                             Integer startStationId,
+                                             Integer targetStationId,
+                                             Double pathLenFactor) {
         NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
         if (navigateUtils == null) {
             return new ArrayList<>();
         }
-        List<NavigateNode> nodes = navigateUtils.calcByStationId(startStationId, targetStationId);
+        List<NavigateNode> nodes = navigateUtils.calcOptimalPathByStationId(startStationId, targetStationId, taskNo, pathLenFactor);
         List<Integer> ids = new ArrayList<>();
         for (NavigateNode n : nodes) {
             JSONObject v = JSONObject.parseObject(n.getNodeValue());
@@ -324,12 +401,19 @@
             segCmd.setCommandType(original.getCommandType());
             segCmd.setPalletSize(original.getPalletSize());
             segCmd.setNavigatePath(new ArrayList<>(path.subList(0, currentEndIdx + 1)));
-            sendCommand(segCmd);
+            if (!sendSegmentWithRetry(segCmd, original.getTaskNo())) {
+                return;
+            }
 
             long runTime = System.currentTimeMillis();
             boolean firstRun = true;
             while (true) {
                 try {
+                    Object cancel = redisUtil.get(RedisKeyType.DEVICE_STATION_MOVE_RESET.key + original.getTaskNo());
+                    if (cancel != null) {
+                        break;//鏀跺埌涓柇淇″彿
+                    }
+
                     StationProtocol currentStation = findCurrentStationByTask(original.getTaskNo());
                     if (currentStation == null) {
                         if(System.currentTimeMillis() - runTime > 1000 * 60){
@@ -370,18 +454,8 @@
                         nextCmd.setPalletSize(original.getPalletSize());
                         nextCmd.setNavigatePath(new ArrayList<>(path.subList(currentStartIdx, currentEndIdx + 1)));
                         nextCmd.setOriginalNavigatePath(path);
-                        while (true) {
-                            CommandResponse commandResponse = sendCommand(nextCmd);
-                            if (commandResponse == null) {
-                                Thread.sleep(200);
-                                continue;
-                            }
-
-                            if (commandResponse.getResult()) {
-                                break;
-                            }
-
-                            Thread.sleep(200);
+                        if (!sendSegmentWithRetry(nextCmd, original.getTaskNo())) {
+                            break;
                         }
                     }
                     Thread.sleep(500);
@@ -401,7 +475,7 @@
             if (deviceConfigService == null) {
                 return null;
             }
-            List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+            List<DeviceConfig> devpList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                     .eq("device_type", String.valueOf(SlaveType.Devp)));
             for (DeviceConfig dc : devpList) {
                 com.zy.core.thread.StationThread t = (com.zy.core.thread.StationThread) SlaveConnection.get(SlaveType.Devp, dc.getDeviceNo());
@@ -423,4 +497,41 @@
         }
         return null;
     }
+
+    private boolean sendSegmentWithRetry(StationCommand command, Integer taskNo) {
+        while (true) {
+            if (isTaskMoveReset(taskNo)) {
+                return false;
+            }
+            CommandResponse commandResponse = sendCommand(command);
+            if (commandResponse == null) {
+                sleepQuietly(200L);
+                continue;
+            }
+            if (commandResponse.getResult()) {
+                return true;
+            }
+            sleepQuietly(200L);
+        }
+    }
+
+    private boolean isTaskMoveReset(Integer taskNo) {
+        if (taskNo == null || redisUtil == null) {
+            return false;
+        }
+        Object cancel = redisUtil.get(RedisKeyType.DEVICE_STATION_MOVE_RESET.key + taskNo);
+        return cancel != null;
+    }
+
+    private void sleepQuietly(long millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (Exception ignore) {
+        }
+    }
+
+    @Override
+    public boolean clearPath(Integer taskNo) {
+        return false;
+    }
 }

--
Gitblit v1.9.1