From 377e207801eec0014b806394166a68caa52561ab Mon Sep 17 00:00:00 2001
From: Junjie <DELL@qq.com>
Date: 星期三, 07 一月 2026 10:09:20 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/model/command/StationCommand.java         |    7 
 src/main/java/com/zy/core/utils/StationOperateProcessUtils.java     |    9 
 src/main/java/com/zy/core/network/real/ZyStationV3RealConnect.java  |  237 +++++++++
 src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java     |    2 
 src/main/java/com/zy/core/ServerBootstrap.java                      |    3 
 src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java    |   26 
 src/main/java/com/zy/asrs/controller/StationController.java         |    5 
 src/main/java/com/zy/core/thread/StationThread.java                 |    3 
 src/main/java/com/zy/asrs/controller/ConsoleController.java         |    1 
 src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java        |    3 
 src/main/java/com/zy/core/model/protocol/StationProtocol.java       |    3 
 src/main/java/com/zy/core/network/entity/ZyStationStatusEntity.java |    3 
 src/main/java/com/zy/core/network/ZyStationConnectDriver.java       |   18 
 src/main/java/com/zy/core/thread/impl/ZyStationThread.java          |    4 
 src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java        |  390 +++++++++++++++
 src/main/webapp/components/DevpCard.js                              |    1 
 src/main/java/com/zy/core/enums/StationCommandType.java             |   18 
 src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java |  733 +++++++++++++++++++++++++++++
 src/main/java/com/zy/asrs/controller/BasStationOptController.java   |    1 
 src/main/java/com/zy/core/plugin/FakeProcess.java                   |   20 
 20 files changed, 1,454 insertions(+), 33 deletions(-)

diff --git a/src/main/java/com/zy/asrs/controller/BasStationOptController.java b/src/main/java/com/zy/asrs/controller/BasStationOptController.java
index 436c941..5ff4110 100644
--- a/src/main/java/com/zy/asrs/controller/BasStationOptController.java
+++ b/src/main/java/com/zy/asrs/controller/BasStationOptController.java
@@ -43,6 +43,7 @@
         convert(param, wrapper);
         allLike(BasStationOpt.class, param.keySet(), wrapper, condition);
         if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
+        wrapper.orderBy("send_time", false);
         return R.ok(basStationOptService.selectPage(new Page<>(curr, limit), wrapper));
     }
 
diff --git a/src/main/java/com/zy/asrs/controller/ConsoleController.java b/src/main/java/com/zy/asrs/controller/ConsoleController.java
index 466a081..320bf62 100644
--- a/src/main/java/com/zy/asrs/controller/ConsoleController.java
+++ b/src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -116,6 +116,7 @@
                 vo.setEmptyMk(stationProtocol.isEmptyMk()); // 鏄惁绌烘澘
                 vo.setFullPlt(stationProtocol.isFullPlt()); // 鏄惁婊℃澘
                 vo.setRunBlock(stationProtocol.isRunBlock());// 杩愯鍫靛
+                vo.setEnableIn(stationProtocol.isEnableIn());// 鍚姩鍏ュ簱
                 vo.setPalletHeight(stationProtocol.getPalletHeight()); // 鎵樼洏楂樺害
                 vo.setError(stationProtocol.getError()); // 閿欒鐮�
                 vo.setBarcode(stationProtocol.getBarcode()); // 鏉$爜
diff --git a/src/main/java/com/zy/asrs/controller/StationController.java b/src/main/java/com/zy/asrs/controller/StationController.java
index 0a25edb..c90f325 100644
--- a/src/main/java/com/zy/asrs/controller/StationController.java
+++ b/src/main/java/com/zy/asrs/controller/StationController.java
@@ -1,10 +1,9 @@
 package com.zy.asrs.controller;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.zy.asrs.entity.BasDevp;
 import com.zy.asrs.service.BasDevpService;
+import com.zy.core.enums.StationCommandType;
 import com.zy.core.model.StationObjModel;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -68,7 +67,7 @@
             return R.error("绾跨▼涓嶅瓨鍦�");
         }
 
-        StationCommand command = stationThread.getMoveCommand(taskNo, stationId, targetStationId, 0);
+        StationCommand command = stationThread.getCommand(StationCommandType.MOVE, taskNo, stationId, targetStationId, 0);
         MessageQueue.offer(SlaveType.Devp, devpNo, new Task(2, command));
         return R.ok();
     }
diff --git a/src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java b/src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java
index 3d4807b..59fc320 100644
--- a/src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java
+++ b/src/main/java/com/zy/asrs/domain/vo/StationLatestDataVo.java
@@ -35,6 +35,9 @@
     // 杩愯闃诲
     private boolean runBlock;
 
+    // 鍚姩鍏ュ簱
+    private boolean enableIn;
+
     // 鎵樼洏楂樺害
     private Integer palletHeight;
 
diff --git a/src/main/java/com/zy/core/ServerBootstrap.java b/src/main/java/com/zy/core/ServerBootstrap.java
index 4912e40..62c22f5 100644
--- a/src/main/java/com/zy/core/ServerBootstrap.java
+++ b/src/main/java/com/zy/core/ServerBootstrap.java
@@ -11,6 +11,7 @@
 import com.zy.core.thread.impl.ZySiemensCrnThread;
 import com.zy.core.thread.impl.ZySiemensDualCrnThread;
 import com.zy.core.thread.impl.ZyStationThread;
+import com.zy.core.thread.impl.ZyStationV3Thread;
 import com.zy.core.thread.impl.ZyRgvThread;
 
 import lombok.extern.slf4j.Slf4j;
@@ -134,6 +135,8 @@
                 ThreadHandler thread = null;
                 if (deviceConfig.getThreadImpl().equals("ZyStationThread")) {
                     thread = new ZyStationThread(deviceConfig, redisUtil);
+                } else if (deviceConfig.getThreadImpl().equals("ZyStationV3Thread")) {
+                    thread = new ZyStationV3Thread(deviceConfig, redisUtil);
                 } else {
                     throw new CoolException("鏈煡鐨勭嚎绋嬪疄鐜�");
                 }
diff --git a/src/main/java/com/zy/core/enums/StationCommandType.java b/src/main/java/com/zy/core/enums/StationCommandType.java
new file mode 100644
index 0000000..e1890ab
--- /dev/null
+++ b/src/main/java/com/zy/core/enums/StationCommandType.java
@@ -0,0 +1,18 @@
+package com.zy.core.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum StationCommandType {
+    MOVE("MOVE", "绉诲姩"),
+    WRITE_INFO("WRITE_INFO", "淇℃伅鍐欏叆"),
+    RESET("RESET", "澶嶄綅");
+
+    private final String code;
+    private final String desc;
+
+    StationCommandType(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+}
diff --git a/src/main/java/com/zy/core/model/command/StationCommand.java b/src/main/java/com/zy/core/model/command/StationCommand.java
index af12e44..825fea0 100644
--- a/src/main/java/com/zy/core/model/command/StationCommand.java
+++ b/src/main/java/com/zy/core/model/command/StationCommand.java
@@ -1,6 +1,9 @@
 package com.zy.core.model.command;
 
 import lombok.Data;
+import java.util.List;
+
+import com.zy.core.enums.StationCommandType;
 
 @Data
 public class StationCommand {
@@ -14,4 +17,8 @@
     // 鎵樼洏澶у皬锛屽鏃犵壒娈婃儏鍐碉紝榛樿0
     private Integer palletSize;
 
+    private List<Integer> navigatePath;
+
+    private StationCommandType commandType;
+
 }
diff --git a/src/main/java/com/zy/core/model/protocol/StationProtocol.java b/src/main/java/com/zy/core/model/protocol/StationProtocol.java
index 645f225..566f8d9 100644
--- a/src/main/java/com/zy/core/model/protocol/StationProtocol.java
+++ b/src/main/java/com/zy/core/model/protocol/StationProtocol.java
@@ -40,6 +40,9 @@
     // 杩愯闃诲
     private boolean runBlock;
 
+    // 鍚姩鍏ュ簱
+    private boolean enableIn;
+
     // 鎵樼洏楂樺害
     private Integer palletHeight;
 
diff --git a/src/main/java/com/zy/core/network/ZyStationConnectDriver.java b/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
index 185902d..78be50b 100644
--- a/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
+++ b/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
@@ -9,7 +9,9 @@
 import com.zy.core.network.entity.ZyStationStatusEntity;
 import java.util.List;
 import com.zy.core.network.fake.ZyStationFakeConnect;
+import com.zy.core.network.fake.ZyStationFakeSegConnect;
 import com.zy.core.network.real.ZyStationRealConnect;
+import com.zy.core.network.real.ZyStationV3RealConnect;
 import lombok.extern.slf4j.Slf4j;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -23,6 +25,7 @@
 public class ZyStationConnectDriver implements ThreadHandler {
 
     private static final ZyStationFakeConnect zyStationFakeConnect = new ZyStationFakeConnect();
+    private static final ZyStationFakeSegConnect zyStationFakeSegConnect = new ZyStationFakeSegConnect();
 
     private boolean connected = false;
     private DeviceConfig deviceConfig;
@@ -44,10 +47,19 @@
     @Override
     public boolean connect() {
         if (deviceConfig.getFake() == 0) {
-            zyStationConnectApi = new ZyStationRealConnect(deviceConfig, redisUtil);
+            if ("ZyStationV3Thread".equals(deviceConfig.getThreadImpl())) {
+                zyStationConnectApi = new ZyStationV3RealConnect(deviceConfig, redisUtil);
+            } else {
+                zyStationConnectApi = new ZyStationRealConnect(deviceConfig, redisUtil);
+            }
         } else {
-            zyStationFakeConnect.addFakeConnect(deviceConfig, redisUtil);
-            zyStationConnectApi = zyStationFakeConnect;
+            if ("ZyStationV3Thread".equals(deviceConfig.getThreadImpl())) {
+                zyStationFakeSegConnect.addFakeConnect(deviceConfig, redisUtil);
+                zyStationConnectApi = zyStationFakeSegConnect;
+            } else {
+                zyStationFakeConnect.addFakeConnect(deviceConfig, redisUtil);
+                zyStationConnectApi = zyStationFakeConnect;
+            }
         }
 
         boolean connect = zyStationConnectApi.connect();
diff --git a/src/main/java/com/zy/core/network/entity/ZyStationStatusEntity.java b/src/main/java/com/zy/core/network/entity/ZyStationStatusEntity.java
index 3959d31..48f9b3e 100644
--- a/src/main/java/com/zy/core/network/entity/ZyStationStatusEntity.java
+++ b/src/main/java/com/zy/core/network/entity/ZyStationStatusEntity.java
@@ -50,6 +50,9 @@
     //杩愯鍫靛
     private boolean runBlock = false;
 
+    //鍚姩鍏ュ簱
+    private boolean enableIn = false;
+
     @Override
     public ZyStationStatusEntity clone() {
         try {
diff --git a/src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java b/src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java
index 419b417..99d4dd9 100644
--- a/src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java
+++ b/src/main/java/com/zy/core/network/fake/ZyStationFakeConnect.java
@@ -11,6 +11,7 @@
 import com.zy.common.utils.RedisUtil;
 import com.zy.core.News;
 import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.StationCommandType;
 import com.zy.core.model.CommandResponse;
 import com.zy.core.model.command.StationCommand;
 import com.zy.core.network.api.ZyStationConnectApi;
@@ -116,24 +117,29 @@
         Integer taskNo = command.getTaskNo();
         Integer stationId = command.getStationId();
         Integer targetStationId = command.getTargetStaNo();
+        StationCommandType commandType = command.getCommandType();
         boolean generateBarcode = false;
 
-        if(taskNo == 0 && targetStationId == 0){
-            //娓呯┖绔欑偣
-            resetStation(deviceNo, stationId);
-            return;
+        if(commandType == StationCommandType.RESET){
+            if(taskNo == 0 && targetStationId == 0){
+                //娓呯┖绔欑偣
+                resetStation(deviceNo, stationId);
+                return;
+            }
+        }
+
+        if(commandType == StationCommandType.WRITE_INFO){
+            if (taskNo == 9998 && targetStationId == 0) {
+                //鐢熸垚鍑哄簱绔欑偣浠跨湡鏁版嵁
+                generateFakeOutStationData(deviceNo, stationId);
+                return;
+            }
         }
 
         //浠诲姟鍙峰睘浜庝豢鐪熷叆搴撲换鍔″彿
         if (checkTaskNoInArea(taskNo)) {
             //鐢熸垚浠跨湡鏁版嵁
             generateBarcode = true;
-        }
-
-        if (taskNo == 9998 && targetStationId == 0) {
-            //鐢熸垚鍑哄簱绔欑偣浠跨湡鏁版嵁
-            generateFakeOutStationData(deviceNo, stationId);
-            return;
         }
 
         if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) {
diff --git a/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java b/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
new file mode 100644
index 0000000..9680550
--- /dev/null
+++ b/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
@@ -0,0 +1,733 @@
+package com.zy.core.network.fake;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.zy.asrs.entity.DeviceConfig;
+import com.zy.common.model.NavigateNode;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.News;
+import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.StationCommandType;
+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.HashMap;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.Map;
+import java.util.function.Supplier;
+
+public class ZyStationFakeSegConnect implements ZyStationConnectApi {
+
+    private static int LOCK_STATION = 0;
+    private HashMap<Integer, List<ZyStationStatusEntity>> deviceStatusMap = new HashMap<>();
+    private HashMap<Integer, DeviceConfig> deviceConfigMap = new HashMap<>();
+    private RedisUtil redisUtil;
+    private final Map<Integer, BlockingQueue<StationCommand>> taskQueues = new ConcurrentHashMap<>();
+    private final Map<Integer, Long> taskLastUpdateTime = new ConcurrentHashMap<>();
+    private final Map<Integer, Boolean> taskRunning = new ConcurrentHashMap<>();
+    private final ExecutorService executor = Executors.newCachedThreadPool();
+
+    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
+    public boolean connect() {
+        return true;
+    }
+
+    @Override
+    public boolean disconnect() {
+        executor.shutdownNow();
+        return true;
+    }
+
+    @Override
+    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 : 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);
+                    status.setError(0);
+                    status.setBarcode("");
+                }
+            }
+        }
+
+        return statusList;
+    }
+
+    @Override
+    public CommandResponse sendCommand(Integer deviceNo, StationCommand command) {
+        Integer taskNo = command.getTaskNo();
+        if (taskNo == null) {
+            return new CommandResponse(false, "浠诲姟鍙蜂负绌�");
+        }
+
+        taskQueues.computeIfAbsent(taskNo, k -> new LinkedBlockingQueue<>()).offer(command);
+        taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
+
+        if (taskRunning.putIfAbsent(taskNo, true) == null) {
+            executor.submit(() -> runTaskLoop(deviceNo, taskNo));
+        }
+
+        return new CommandResponse(true, "鍛戒护宸插彈鐞嗭紙寮傛鎵ц锛�");
+    }
+
+    private void runTaskLoop(Integer deviceNo, Integer taskNo) {
+        try {
+            // 鐢ㄤ簬瀛樺偍褰撳墠浠诲姟寰呮墽琛岀殑瀹屾暣璺緞闃熷垪
+            BlockingQueue<Integer> pathQueue = new LinkedBlockingQueue<>();
+            // 褰撳墠鏄惁姝e湪鎵ц绉诲姩
+            boolean isMoving = false;
+            // 褰撳墠绉诲姩鍒扮殑璺緞绱㈠紩
+            int currentPathIndex = 0;
+            // 瀹屾暣璺緞璁板綍
+            List<Integer> fullPath = new ArrayList<>();
+            
+            StationCommand initialCommand = null;
+            Integer finalTargetStationId = null;
+            boolean generateBarcode = false;
+
+            while (true) {
+                BlockingQueue<StationCommand> commandQueue = taskQueues.get(taskNo);
+                if (commandQueue == null) {
+                    break;
+                }
+
+                // 灏濊瘯鑾峰彇鏂板懡浠わ紝濡傛灉娌℃湁鏂板懡浠ゅ垯缁х画鎵ц鐜版湁璺緞
+                StationCommand command = commandQueue.poll(100, TimeUnit.MILLISECONDS);
+                if (command != null) {
+                    taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
+                    
+                    if (initialCommand == null) {
+                        initialCommand = command;
+                        finalTargetStationId = command.getTargetStaNo();
+                        if (checkTaskNoInArea(taskNo)) {
+                            generateBarcode = true;
+                        }
+                    }
+
+                    List<Integer> newPath = command.getNavigatePath();
+                    if (newPath != null && !newPath.isEmpty()) {
+                        // 濡傛灉鏄涓�娈佃矾寰�
+                        if (fullPath.isEmpty()) {
+                            fullPath.addAll(newPath);
+                            for (Integer stationId : newPath) {
+                                pathQueue.offer(stationId);
+                            }
+                        } else {
+                            // 杩藉姞璺緞锛岄渶瑕佸幓閲嶈鎺ョ偣
+                            Integer lastStationId = fullPath.get(fullPath.size() - 1);
+                            int startIndex = 0;
+                            if (!newPath.isEmpty() && newPath.get(0).equals(lastStationId)) {
+                                startIndex = 1;
+                            }
+                            for (int i = startIndex; i < newPath.size(); i++) {
+                                Integer stationId = newPath.get(i);
+                                fullPath.add(stationId);
+                                pathQueue.offer(stationId);
+                            }
+                        }
+                    }
+                    
+                    // 澶勭悊闈炵Щ鍔ㄥ懡浠�
+                    if (command.getCommandType() != StationCommandType.MOVE) {
+                        handleCommand(deviceNo, command);
+                    }
+                }
+
+                // 鎵ц绉诲姩閫昏緫
+                if (!pathQueue.isEmpty()) {
+                    // 濡傛灉鍒氬紑濮嬶紝鍏堝垵濮嬪寲褰撳墠浣嶇疆
+                    if (currentPathIndex == 0 && !fullPath.isEmpty()) {
+                         Integer startStationId = fullPath.get(0);
+                         Integer deviceId = getDeviceNoByStationId(startStationId);
+                         if (deviceId != null) {
+                             initStationMove(taskNo, startStationId, deviceId, taskNo, finalTargetStationId, true, null);
+                         }
+                    }
+
+                    // 鍙栧嚭涓嬩竴涓洰鏍囩偣
+                    Integer nextStationId = pathQueue.peek(); // 杩欓噷鐨勯�昏緫闇�瑕佹敼涓洪�愪釜琛岃蛋
+                    // 瀹為檯琛岃蛋閫昏緫搴旇鏄湪杩欓噷娑堣垂 pathQueue
+                    // 涓轰簡绠�鍖栵紝鎴戜滑灏� pathQueue 杞负 stationMoveByPathIds 鐨勯�昏緫锛屼絾杩欓噷闇�瑕佹敼閫犳垚姝ヨ繘寮�
+                    
+                    // 閲嶆柊璁捐锛歳unTaskLoop 璐熻矗涓嶆柇娑堣垂 pathQueue 骞舵墽琛屽崟姝ョЩ鍔�
+                    if (nextStationId != null) {
+                        Integer currentStationId = fullPath.get(currentPathIndex);
+                        if (currentStationId.equals(nextStationId)) {
+                            pathQueue.poll(); // 绉婚櫎宸插埌杈剧殑鐐�
+                            continue;
+                        }
+                        
+                        // 鎵ц浠� currentStationId 鍒� nextStationId 鐨勭Щ鍔�
+                        Integer currentDeviceNo = getDeviceNoByStationId(currentStationId);
+                        Integer nextDeviceNo = getDeviceNoByStationId(nextStationId);
+                        
+                        if (currentDeviceNo != null && nextDeviceNo != null) {
+                            boolean moveSuccess = stationMoveToNext(taskNo, currentStationId, currentDeviceNo, nextStationId, nextDeviceNo, taskNo, finalTargetStationId);
+                            if (moveSuccess) {
+                                currentPathIndex++;
+                                pathQueue.poll();
+                                sleep(1000); // 妯℃嫙鑰楁椂
+                            } else {
+                                sleep(1000); // 澶辫触閲嶈瘯绛夊緟
+                            }
+                        } else {
+                            pathQueue.poll(); // 鏃犳硶鎵ц锛岃烦杩�
+                        }
+                    }
+                } else {
+                    // 闃熷垪涓虹┖锛屾鏌ユ槸鍚﹁秴鏃�
+                    Long lastTime = taskLastUpdateTime.get(taskNo);
+                    if (lastTime != null && System.currentTimeMillis() - lastTime > 30000) {
+                        // 瀹屾垚浠诲姟鍚庢竻鐞�
+                        if (fullPath.size() > 0 && generateBarcode) {
+                             Integer lastStation = fullPath.get(fullPath.size()-1);
+                             Integer lastDevice = getDeviceNoByStationId(lastStation);
+                             if (lastDevice != null) {
+                                 generateStationBarcode(taskNo, finalTargetStationId, lastDevice);
+                             }
+                        }
+                        break;
+                    }
+                }
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        } finally {
+            taskQueues.remove(taskNo);
+            taskLastUpdateTime.remove(taskNo);
+            taskRunning.remove(taskNo);
+        }
+    }
+
+    @Override
+    public CommandResponse sendOriginCommand(String address, short[] data) {
+        return new CommandResponse(true, "鍘熷鍛戒护宸插彈鐞嗭紙寮傛鎵ц锛�");
+    }
+
+    @Override
+    public byte[] readOriginCommand(String address, int length) {
+        return new byte[0];
+    }
+
+    private void handleCommand(Integer deviceNo, StationCommand command) {
+        News.info("[WCS Debug] 绔欑偣浠跨湡妯℃嫙(V3)宸插惎鍔紝鍛戒护鏁版嵁={}", JSON.toJSONString(command));
+        Integer taskNo = command.getTaskNo();
+        Integer stationId = command.getStationId();
+        Integer targetStationId = command.getTargetStaNo();
+        boolean generateBarcode = false;
+
+        if (command.getCommandType() == StationCommandType.RESET) {
+            resetStation(deviceNo, stationId);
+            return;
+        }
+
+        if (checkTaskNoInArea(taskNo)) {
+            generateBarcode = true;
+        }
+
+        if (command.getCommandType() == StationCommandType.WRITE_INFO) {
+            if (taskNo == 9998 && targetStationId == 0) {
+                //鐢熸垚鍑哄簱绔欑偣浠跨湡鏁版嵁
+                generateFakeOutStationData(deviceNo, stationId);
+                return;
+            }
+        }
+
+        if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) {
+            generateStationData(deviceNo, taskNo, stationId, targetStationId);
+        }
+
+        List<Integer> navigatePath = command.getNavigatePath();
+        if (navigatePath != null && !navigatePath.isEmpty()) {
+            segmentedPathCommand(command, generateBarcode);
+            return;
+        }
+    }
+
+    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) {
+            return;
+        }
+
+        synchronized (status) {
+            status.setLoading(true);
+        }
+    }
+
+    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) {
+            return;
+        }
+
+        synchronized (status) {
+            status.setTaskNo(taskNo);
+            status.setTargetStaNo(targetStationId);
+        }
+    }
+
+    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;
+        }
+
+        synchronized (status) {
+            status.setTaskNo(0);
+            status.setLoading(false);
+            status.setBarcode("");
+        }
+    }
+
+    private void segmentedPathCommand(StationCommand command, boolean generateBarcode) {
+        Integer taskNo = command.getTaskNo();
+        Integer finalTargetStationId = command.getTargetStaNo();
+        List<Integer> path = command.getNavigatePath();
+        if (path == null || path.isEmpty()) {
+            return;
+        }
+        
+        Integer currentStationId = findCurrentStationIdByTask(taskNo);
+        int startIdx = 0;
+        if (currentStationId != null) {
+            int idx = path.indexOf(currentStationId);
+            if (idx >= 0) {
+                startIdx = idx;
+            }
+        }
+        
+        Integer segmentTargetStationId = path.get(path.size() - 1);
+        int endIdx = path.size() - 1;
+        
+        boolean isFinalSegment = segmentTargetStationId.equals(finalTargetStationId);
+        boolean appendMode = currentStationId != null && path.indexOf(currentStationId) >= 0;
+        boolean generateBarcodeFinal = generateBarcode && isFinalSegment;
+        
+        stationMoveByPathIds(path, taskNo, finalTargetStationId, false, generateBarcodeFinal, startIdx, endIdx, appendMode);
+    }
+
+    private Integer getDeviceNoByStationId(Integer stationId) {
+        for (Integer devNo : deviceStatusMap.keySet()) {
+            List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
+            if (list == null) {
+                continue;
+            }
+            for (ZyStationStatusEntity e : list) {
+                if (e.getStationId() != null && e.getStationId().equals(stationId)) {
+                    return devNo;
+                }
+            }
+        }
+        return null;
+    }
+
+    private Integer findCurrentStationIdByTask(Integer taskNo) {
+        for (Integer devNo : deviceStatusMap.keySet()) {
+            List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
+            if (list == null) {
+                continue;
+            }
+            for (ZyStationStatusEntity e : list) {
+                if (e.getTaskNo() != null && e.getTaskNo().equals(taskNo) && e.isLoading()) {
+                    return e.getStationId();
+                }
+            }
+        }
+        return null;
+    }
+
+    private boolean stationMoveByPathIds(List<Integer> stationPath, Integer taskNo, Integer targetStationId, boolean clearData, boolean generateBarcode, int startIdx, int endIdx, boolean appendMode) {
+        Integer lastStationId = null;
+        Integer targetStationDeviceNo = getDeviceNoByStationId(targetStationId);
+        long executeTime = System.currentTimeMillis();
+        int i = Math.max(0, startIdx);
+        while (i < stationPath.size() && i <= endIdx) {
+            if (Thread.currentThread().isInterrupted()) {
+                return false;
+            }
+            Integer currentStationId = stationPath.get(i);
+            Integer currentStationDeviceNo = getDeviceNoByStationId(currentStationId);
+            if (currentStationDeviceNo == null) {
+                return false;
+            }
+
+            Integer nextStationId = null;
+            Integer nextStationDeviceNo = null;
+            try {
+                nextStationId = stationPath.get(i + 1);
+                nextStationDeviceNo = getDeviceNoByStationId(nextStationId);
+            } catch (Exception ignore) {}
+
+            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 == startIdx && !appendMode) {
+                boolean result = initStationMove(taskNo, currentStationId, currentStationDeviceNo, taskNo, targetStationId, true, null);
+                if (!result) {
+                    continue;
+                }
+                sleep(1000);
+                if (Thread.currentThread().isInterrupted()) {
+                    return false;
+                }
+            }
+
+            if (nextStationId != null && nextStationDeviceNo != null) {
+                boolean result = stationMoveToNext(taskNo, currentStationId, currentStationDeviceNo, nextStationId, nextStationDeviceNo, taskNo, targetStationId);
+                if (!result) {
+                    continue;
+                }
+                lastStationId = currentStationId;
+            }
+
+            if (currentStationId.equals(targetStationId)) {
+                break;
+            }
+
+            i++;
+            executeTime = System.currentTimeMillis();
+            sleep(1000);
+            if (Thread.currentThread().isInterrupted()) {
+                return false;
+            }
+        }
+
+        if (generateBarcode) {
+            if (lastStationId != null && targetStationDeviceNo != null) {
+                while (true) {
+                    if (Thread.currentThread().isInterrupted()) {
+                        break;
+                    }
+                    boolean result = generateStationBarcode(taskNo, targetStationId, targetStationDeviceNo);
+                    sleep(1000);
+                    if (!result) {
+                        continue;
+                    }
+                    break;
+                }
+            }
+        }
+
+        if (clearData) {
+            sleep(10000);
+            if (Thread.currentThread().isInterrupted()) {
+                return true;
+            }
+            if (lastStationId != null && targetStationDeviceNo != null) {
+                while (true) {
+                    if (Thread.currentThread().isInterrupted()) {
+                        break;
+                    }
+                    boolean result = clearStation(targetStationDeviceNo, taskNo, targetStationId);
+                    sleep(1000);
+                    if (!result) {
+                        continue;
+                    }
+                    break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    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 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;
+        }
+
+        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);
+        }
+
+        if (runBlock != null) {
+            currentStatus.setRunBlock(runBlock);
+        }
+        return true;
+    }
+
+    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);
+
+            if (currentStatus == null) {
+                return false;
+            }
+
+            if (currentStatus.getTaskNo() > 0) {
+                if (!currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) {
+                    return false;
+                }
+            }
+
+            boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, taskNo, targetStationId, isLoading, barcode, false);
+            if (!result) {
+                return false;
+            }
+            return true;
+        });
+
+        return executeResult;
+    }
+
+    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 = nextStatusList.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, nextStationDeviceNo, taskNo, targetStaNo, true, null, false);
+            if (!result) {
+                return false;
+            }
+
+            boolean result2 = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, 0, 0, false, "", false);
+            if (!result2) {
+                return false;
+            }
+
+            return true;
+        });
+        return executeResult;
+    }
+
+    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);
+
+            if (currentStatus == null) {
+                return false;
+            }
+
+            Random random = new Random();
+
+            String barcodeTime = String.valueOf(System.currentTimeMillis());
+            String barcode = String.valueOf(random.nextInt(10)) + String.valueOf(random.nextInt(10)) + barcodeTime.substring(7);
+
+            boolean result = updateStationData(lockTaskNo, currentStationId, currentStationDeviceNo, null, null, null, barcode, null);
+            if (!result) {
+                return false;
+            }
+            return true;
+        });
+
+        return executeResult;
+    }
+
+    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);
+
+            if (currentStatus == null) {
+                return 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;
+            }
+            return true;
+        });
+
+        return executeResult;
+    }
+
+    public boolean lockExecute(Integer taskNo, Supplier<Boolean> function) {
+        if (!setLockStation(taskNo)) {
+            return false;
+        }
+
+        boolean result = function.get();
+        releaseLockStation(taskNo);
+        return result;
+    }
+
+    private 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;
+    }
+}
diff --git a/src/main/java/com/zy/core/network/real/ZyStationV3RealConnect.java b/src/main/java/com/zy/core/network/real/ZyStationV3RealConnect.java
new file mode 100644
index 0000000..8f0af83
--- /dev/null
+++ b/src/main/java/com/zy/core/network/real/ZyStationV3RealConnect.java
@@ -0,0 +1,237 @@
+package com.zy.core.network.real;
+
+import HslCommunication.Core.Types.OperateResult;
+import HslCommunication.Core.Types.OperateResultExOne;
+import HslCommunication.Profinet.Siemens.SiemensPLCS;
+import HslCommunication.Profinet.Siemens.SiemensS7Net;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.DateUtils;
+import com.core.common.SpringUtils;
+import com.zy.asrs.entity.BasDevp;
+import com.zy.asrs.entity.DeviceConfig;
+import com.zy.asrs.service.BasDevpService;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.News;
+import com.zy.core.cache.OutputQueue;
+import com.zy.core.enums.StationCommandType;
+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 lombok.extern.slf4j.Slf4j;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 杈撻�佺珯鐪熷疄杩炴帴锛圥LC锛�
+ */
+@Slf4j
+public class ZyStationV3RealConnect implements ZyStationConnectApi {
+
+    private List<ZyStationStatusEntity> statusList;
+    private List<ZyStationStatusEntity> barcodeStatusList;
+    private SiemensS7Net siemensNet;
+    private DeviceConfig deviceConfig;
+    private RedisUtil redisUtil;
+    private final static int taskAddressLength = 48;
+    private final static int taskAddressLimit = 50;
+
+    public ZyStationV3RealConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) {
+        this.deviceConfig = deviceConfig;
+        this.redisUtil = redisUtil;
+    }
+
+    @Override
+    public boolean connect() {
+        boolean connected = false;
+        siemensNet = new SiemensS7Net(SiemensPLCS.S1200, deviceConfig.getIp());
+        OperateResult connect = siemensNet.ConnectServer();
+        if (connect.IsSuccess) {
+            connected = true;
+            OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆戣緭閫佺珯plc杩炴帴鎴愬姛 ===>> [id:{1}] [ip:{2}] [port:{3}]",
+                    DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(),
+                    deviceConfig.getPort()));
+            News.info("杈撻�佺珯plc杩炴帴鎴愬姛 ===>> [id:{}] [ip:{}] [port:{}]",
+                    deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort());
+        } else {
+            OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆戣緭閫佺珯plc杩炴帴澶辫触锛侊紒锛� ===>> [id:{1}] [ip:{2}] [port:{3}]",
+                    DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(),
+                    deviceConfig.getPort()));
+            News.error("杈撻�佺珯plc杩炴帴澶辫触锛侊紒锛� ===>> [id:{}] [ip:{}] [port:{}]",
+                    deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort());
+        }
+        return connected;
+    }
+
+    @Override
+    public boolean disconnect() {
+        siemensNet.ConnectClose();
+        return true;
+    }
+
+    @Override
+    public List<ZyStationStatusEntity> getStatus(Integer deviceNo) {
+        if (statusList == null) {
+            BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
+            if (basDevpService == null) {
+                return Collections.emptyList();
+            }
+
+            BasDevp basDevp = basDevpService
+                    .selectOne(new EntityWrapper<BasDevp>().eq("devp_no", deviceConfig.getDeviceNo()));
+            if (basDevp == null) {
+                return Collections.emptyList();
+            }
+
+            statusList = JSONObject.parseArray(basDevp.getStationList(), ZyStationStatusEntity.class);
+            if (statusList != null) {
+                statusList.sort(Comparator.comparing(ZyStationStatusEntity::getStationId));
+            }
+            barcodeStatusList = JSONObject.parseArray(basDevp.getBarcodeStationList(), ZyStationStatusEntity.class);
+            if (barcodeStatusList != null) {
+                barcodeStatusList.sort(Comparator.comparing(ZyStationStatusEntity::getStationId));
+            }
+        }
+
+        OperateResultExOne<byte[]> result = siemensNet.Read("DB100.0", (short) (statusList.size() * 8));
+        if (result.IsSuccess) {
+            for (int i = 0; i < statusList.size(); i++) {
+                ZyStationStatusEntity statusEntity = statusList.get(i); // 绔欑偣缂栧彿
+                statusEntity.setTaskNo(siemensNet.getByteTransform().TransInt32(result.Content, i * 8)); // 宸ヤ綔鍙�
+                statusEntity.setTargetStaNo((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 8 + 4)); // 鐩爣绔�
+
+                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, i * 8 + 6, 1);
+                statusEntity.setAutoing(status[0]); // 鑷姩
+                statusEntity.setLoading(status[1]); // 鏈夌墿
+                statusEntity.setInEnable(status[2]); // 鍙叆
+                statusEntity.setOutEnable(status[3]);// 鍙嚭
+                statusEntity.setEmptyMk(status[4]); // 绌烘墭鐩�
+                statusEntity.setFullPlt(status[5]); // 婊℃墭鐩�
+
+                boolean[] status2 = siemensNet.getByteTransform().TransBool(result.Content, i * 8 + 7, 1);
+                statusEntity.setRunBlock(status2[1]);//閲嶆柊瑙勫垝璺嚎
+                statusEntity.setEnableIn(status2[3]);//鍚姩鍏ュ簱
+            }
+        }
+
+        // 鏉$爜鎵弿鍣�
+        OperateResultExOne<byte[]> result2 = siemensNet.Read("DB101.0", (short) (statusList.size() * 10));
+        if (result2.IsSuccess) {
+            for (int i = 0; i < barcodeStatusList.size(); i++) {
+                ZyStationStatusEntity barcodeEntity = barcodeStatusList.get(i);
+                ZyStationStatusEntity statusEntity = findStatusEntity(barcodeEntity.getStationId());
+                if (statusEntity == null) {
+                    continue;
+                }
+                String barcode = siemensNet.getByteTransform().TransString(result2.Content, i * 10 + 2, 8, "UTF-8");
+                barcode = barcode.trim();
+                barcodeEntity.setBarcode(barcode);
+            }
+        }
+
+        return statusList;
+    }
+
+    @Override
+    public CommandResponse sendCommand(Integer deviceNo, StationCommand command) {
+        CommandResponse commandResponse = new CommandResponse(false);
+        if (null == command) {
+            commandResponse.setMessage("鍛戒护涓虹┖");
+            return commandResponse;
+        }
+
+        if (command.getCommandType().equals(StationCommandType.MOVE)) {
+            int enableCommandIdx = -1;
+            while (true) {
+                enableCommandIdx = getEnableCommandIdx();
+                if(enableCommandIdx == -1) {
+                    try {
+                        Thread.sleep(300);
+                    }catch (Exception e) {}
+                }else {
+                    break;
+                }
+            }
+
+            List<Integer> pathList = command.getNavigatePath();
+
+            short[] data = new short[22];
+            data[0] = command.getTargetStaNo().shortValue();
+
+            int dataIdx = 1;
+            for (Integer path : pathList) {
+                data[dataIdx++] = path.shortValue();
+            }
+
+            OperateResult writeTask = siemensNet.Write("DB23." + enableCommandIdx * taskAddressLength, command.getTaskNo());
+            OperateResult writeData = siemensNet.Write("DB23." + enableCommandIdx * taskAddressLength + 4, data);
+            if(writeTask.IsSuccess &&  writeData.IsSuccess) {
+                log.error("鍐欏叆杈撻�佺嚎鍛戒护鎴愬姛銆備换鍔″彿={}锛岀珯鐐规暟鎹�={}", command.getTaskNo(), JSON.toJSON(command));
+                commandResponse.setResult(true);
+            }else {
+                log.error("鍐欏叆杈撻�佺嚎鍛戒护澶辫触銆傜珯鐐圭紪鍙�={}锛岀珯鐐规暟鎹�={}", command.getTaskNo(), JSON.toJSON(command));
+                commandResponse.setResult(false);
+            }
+        }
+        return commandResponse;
+    }
+
+    @Override
+    public CommandResponse sendOriginCommand(String address, short[] data) {
+        CommandResponse commandResponse = new CommandResponse(false);
+        if (null == data || data.length == 0) {
+            commandResponse.setMessage("鏁版嵁涓虹┖");
+            return commandResponse;
+        }
+
+        OperateResult write = siemensNet.Write(address, data);
+        if (write.IsSuccess) {
+            log.info("鍐欏叆鍘熷鍛戒护鎴愬姛銆傚湴鍧�={}锛屾暟鎹�={}", address, JSON.toJSON(data));
+            commandResponse.setResult(true);
+        } else {
+            log.error("鍐欏叆鍘熷鍛戒护澶辫触銆傚湴鍧�={}锛屾暟鎹�={}", address, JSON.toJSON(data));
+            commandResponse.setResult(false);
+        }
+        return commandResponse;
+    }
+
+    @Override
+    public byte[] readOriginCommand(String address, int length) {
+        OperateResultExOne<byte[]> result = siemensNet.Read(address, (short) length);
+        if (result.IsSuccess) {
+            return result.Content;
+        }
+        return new byte[0];
+    }
+
+    private ZyStationStatusEntity findStatusEntity(Integer stationId) {
+        for (ZyStationStatusEntity statusEntity : statusList) {
+            if (statusEntity.getStationId().equals(stationId)) {
+                return statusEntity;
+            }
+        }
+        return null;
+    }
+
+    private int getEnableCommandIdx() {
+        int useIdx = -1;
+        for (int i = 0; i < taskAddressLimit; i++) {
+            OperateResultExOne<byte[]> result = siemensNet.Read("DB23." + i * taskAddressLength, (short) taskAddressLength);
+            int taskStatus = siemensNet.getByteTransform().TransInt16(result.Content, i * taskAddressLength + 46);
+            if (taskStatus == 1) {
+                continue;
+            }
+
+            useIdx = i;
+            break;
+        }
+        return  useIdx;
+    }
+
+}
diff --git a/src/main/java/com/zy/core/plugin/FakeProcess.java b/src/main/java/com/zy/core/plugin/FakeProcess.java
index c0ca391..9c20eaf 100644
--- a/src/main/java/com/zy/core/plugin/FakeProcess.java
+++ b/src/main/java/com/zy/core/plugin/FakeProcess.java
@@ -236,7 +236,7 @@
                         && !stationProtocol.isLoading()
                         && stationProtocol.getTaskNo() == 0
                 ) {
-                    StationCommand command = stationThread.getMoveCommand(commonService.getWorkNo(WrkIoType.FAKE_TASK_NO.id), stationId, entity.getBarcodeStation().getStationId(), 0);
+                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, commonService.getWorkNo(WrkIoType.FAKE_TASK_NO.id), stationId, entity.getBarcodeStation().getStationId(), 0);
                     MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                     redisUtil.set(RedisKeyType.GENERATE_FAKE_IN_STATION_DATA_LIMIT.key + stationId, "lock", 5);
                 }
@@ -325,7 +325,7 @@
                     taskParam.setBarcode(stationProtocol.getBarcode());
                     WrkMast wrkMast = commonService.createInTask(taskParam);
 
-                    StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationId, stationId, 0);
+                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, stationId, 0);
                     if(command == null){
                         News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                         continue;
@@ -467,7 +467,7 @@
                         taskParam.setBarcode(stationProtocol.getBarcode());
                         WrkMast wrkMast = commonService.createInTask(taskParam);
 
-                        StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationId, stationId, 0);
+                        StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO, wrkMast.getWrkNo(), stationId, stationId, 0);
                         if(command == null){
                             News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                             continue;
@@ -528,7 +528,7 @@
                         continue;
                     }
 
-                    StationCommand command = stationThread.getMoveCommand(0, stationObjModel.getStationId(), 0, 0);
+                    StationCommand command = stationThread.getCommand(StationCommandType.RESET, 0, stationObjModel.getStationId(), 0, 0);
                     if(command == null){
                         continue;
                     }
@@ -576,11 +576,6 @@
                 continue;
             }
 
-            StationCommand command = stationThread.getMoveCommand(0, stationObjModel.getStationId(), 0, 0);
-            if(command == null){
-                continue;
-            }
-
             Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
             StationProtocol stationProtocol = statusMap.get(stationObjModel.getStationId());
             if (stationProtocol == null) {
@@ -588,6 +583,11 @@
             }
 
             if(stationProtocol.getTaskNo() > 0) {
+                StationCommand command = stationThread.getCommand(StationCommandType.RESET, 0, stationObjModel.getStationId(), 0, 0);
+                if(command == null){
+                    continue;
+                }
+
                 WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo());
                 if (wrkMast == null) {
                     MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
@@ -693,7 +693,7 @@
                             continue;
                         }
                         //鐢熸垚浠跨湡绔欑偣鏁版嵁
-                        StationCommand command = stationThread.getMoveCommand(9998, wrkMast.getSourceStaNo(), 0, 0);
+                        StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO, 9998, wrkMast.getSourceStaNo(), 0, 0);
                         MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                     }
                 }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){
diff --git a/src/main/java/com/zy/core/thread/StationThread.java b/src/main/java/com/zy/core/thread/StationThread.java
index b04e391..011083c 100644
--- a/src/main/java/com/zy/core/thread/StationThread.java
+++ b/src/main/java/com/zy/core/thread/StationThread.java
@@ -1,6 +1,7 @@
 package com.zy.core.thread;
 
 import com.zy.core.ThreadHandler;
+import com.zy.core.enums.StationCommandType;
 import com.zy.core.model.CommandResponse;
 import com.zy.core.model.command.StationCommand;
 import com.zy.core.model.protocol.StationProtocol;
@@ -13,7 +14,7 @@
 
     Map<Integer, StationProtocol> getStatusMap();
 
-    StationCommand getMoveCommand(Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize);
+    StationCommand getCommand(StationCommandType commandType, Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize);
 
     CommandResponse sendCommand(StationCommand command);
 
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationThread.java b/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
index b2f598b..be32eb0 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
@@ -20,6 +20,7 @@
 import com.zy.core.cache.OutputQueue;
 import com.zy.core.enums.RedisKeyType;
 import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.StationCommandType;
 import com.zy.core.model.CommandResponse;
 import com.zy.core.model.Task;
 import com.zy.core.model.command.StationCommand;
@@ -179,12 +180,13 @@
     }
 
     @Override
-    public StationCommand getMoveCommand(Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize) {
+    public StationCommand getCommand(StationCommandType commandType, Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize) {
         StationCommand stationCommand = new StationCommand();
         stationCommand.setTaskNo(taskNo);
         stationCommand.setStationId(stationId);
         stationCommand.setTargetStaNo(targetStationId);
         stationCommand.setPalletSize(palletSize);
+        stationCommand.setCommandType(commandType);
         return stationCommand;
     }
 
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
new file mode 100644
index 0000000..70a0cde
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
@@ -0,0 +1,390 @@
+package com.zy.core.thread.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.DateUtils;
+import com.core.common.SpringUtils;
+import com.zy.asrs.entity.BasDevp;
+import com.zy.asrs.entity.BasStationOpt;
+import com.zy.asrs.entity.DeviceConfig;
+import com.zy.asrs.entity.DeviceDataLog;
+import com.zy.asrs.service.BasDevpService;
+import com.zy.asrs.service.BasStationOptService;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.model.NavigateNode;
+import com.zy.common.utils.NavigateUtils;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.cache.MessageQueue;
+import com.zy.core.cache.OutputQueue;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.StationCommandType;
+import com.zy.core.model.CommandResponse;
+import com.zy.core.model.Task;
+import com.zy.core.model.command.StationCommand;
+import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.network.DeviceConnectPool;
+import com.zy.core.network.ZyStationConnectDriver;
+import com.zy.core.network.entity.ZyStationStatusEntity;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.MessageFormat;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@Slf4j
+public class ZyStationV3Thread implements Runnable, com.zy.core.thread.StationThread {
+
+    private List<StationProtocol> statusList = 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);
+
+    public ZyStationV3Thread(DeviceConfig deviceConfig, RedisUtil redisUtil) {
+        this.deviceConfig = deviceConfig;
+        this.redisUtil = redisUtil;
+    }
+
+    @Override
+    @SuppressWarnings("InfiniteLoopStatement")
+    public void run() {
+        this.connect();
+        deviceLogCollectTime = Utils.getDeviceLogCollectTime();
+
+        Thread readThread = new Thread(() -> {
+            while (true) {
+                try {
+                    deviceLogCollectTime = Utils.getDeviceLogCollectTime();
+                    readStatus();
+                    Thread.sleep(100);
+                } catch (Exception e) {
+                    log.error("StationV3Thread Fail", e);
+                }
+            }
+        });
+        readThread.start();
+
+        Thread processThread = new Thread(() -> {
+            while (true) {
+                try {
+                    int step = 1;
+                    Task task = MessageQueue.poll(SlaveType.Devp, deviceConfig.getDeviceNo());
+                    if (task != null) {
+                        step = task.getStep();
+                    }
+                    if (step == 2) {
+                        StationCommand cmd = (StationCommand) task.getData();
+                        executor.submit(() -> executeMoveWithSeg(cmd));
+                    }
+                    Thread.sleep(100);
+                } catch (Exception e) {
+                    log.error("StationV3Process Fail", e);
+                }
+            }
+        });
+        processThread.start();
+    }
+
+    private void readStatus() {
+        if (zyStationConnectDriver == null) {
+            return;
+        }
+
+        if (statusList.isEmpty()) {
+            BasDevpService basDevpService = null;
+            try {
+                basDevpService = SpringUtils.getBean(BasDevpService.class);
+            } catch (Exception e) {
+            }
+            if (basDevpService == null) {
+                return;
+            }
+
+            BasDevp basDevp = basDevpService
+                    .selectOne(new EntityWrapper<BasDevp>().eq("devp_no", deviceConfig.getDeviceNo()));
+            if (basDevp == null) {
+                return;
+            }
+
+            List<ZyStationStatusEntity> list = JSONObject.parseArray(basDevp.getStationList(), ZyStationStatusEntity.class);
+            for (ZyStationStatusEntity entity : list) {
+                StationProtocol stationProtocol = new StationProtocol();
+                stationProtocol.setStationId(entity.getStationId());
+                statusList.add(stationProtocol);
+            }
+        }
+
+        List<ZyStationStatusEntity> zyStationStatusEntities = zyStationConnectDriver.getStatus();
+        for (ZyStationStatusEntity statusEntity : zyStationStatusEntities) {
+            for (StationProtocol stationProtocol : statusList) {
+                if (stationProtocol.getStationId().equals(statusEntity.getStationId())) {
+                    stationProtocol.setTaskNo(statusEntity.getTaskNo());
+                    stationProtocol.setTargetStaNo(statusEntity.getTargetStaNo());
+                    stationProtocol.setAutoing(statusEntity.isAutoing());
+                    stationProtocol.setLoading(statusEntity.isLoading());
+                    stationProtocol.setInEnable(statusEntity.isInEnable());
+                    stationProtocol.setOutEnable(statusEntity.isOutEnable());
+                    stationProtocol.setEmptyMk(statusEntity.isEmptyMk());
+                    stationProtocol.setFullPlt(statusEntity.isFullPlt());
+                    stationProtocol.setPalletHeight(statusEntity.getPalletHeight());
+                    stationProtocol.setError(statusEntity.getError());
+                    stationProtocol.setBarcode(statusEntity.getBarcode());
+                    stationProtocol.setRunBlock(statusEntity.isRunBlock());
+                    stationProtocol.setEnableIn(statusEntity.isEnableIn());
+                }
+            }
+        }
+
+        OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆慬id:{1}] <<<<< 瀹炴椂鏁版嵁鏇存柊鎴愬姛", DateUtils.convert(new Date()), deviceConfig.getDeviceNo()));
+
+        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);
+            deviceDataLogTime = System.currentTimeMillis();
+        }
+    }
+
+    @Override
+    public boolean connect() {
+        zyStationConnectDriver = new ZyStationConnectDriver(deviceConfig, redisUtil);
+        zyStationConnectDriver.start();
+        DeviceConnectPool.put(SlaveType.Devp, deviceConfig.getDeviceNo(), zyStationConnectDriver);
+        return true;
+    }
+
+    @Override
+    public void close() {
+        if (zyStationConnectDriver != null) {
+            zyStationConnectDriver.close();
+        }
+        if (executor != null) {
+            try { executor.shutdownNow(); } catch (Exception ignore) {}
+        }
+    }
+
+    @Override
+    public List<StationProtocol> getStatus() {
+        return statusList;
+    }
+
+    @Override
+    public Map<Integer, StationProtocol> getStatusMap() {
+        Map<Integer, StationProtocol> map = new HashMap<>();
+        for (StationProtocol stationProtocol : statusList) {
+            map.put(stationProtocol.getStationId(), stationProtocol);
+        }
+        return map;
+    }
+
+    @Override
+    public StationCommand getCommand(StationCommandType commandType, Integer taskNo, Integer stationId, Integer targetStationId, Integer palletSize) {
+        StationCommand stationCommand = new StationCommand();
+        stationCommand.setTaskNo(taskNo);
+        stationCommand.setStationId(stationId);
+        stationCommand.setTargetStaNo(targetStationId);
+        stationCommand.setPalletSize(palletSize);
+        stationCommand.setCommandType(commandType);
+
+        if (commandType == StationCommandType.MOVE) {
+            if (!stationId.equals(targetStationId)) {
+                List<Integer> path = calcPathStationIds(stationId, targetStationId);
+                stationCommand.setNavigatePath(path);
+            }
+        }
+        return stationCommand;
+    }
+
+    @Override
+    public CommandResponse sendCommand(StationCommand command) {
+        CommandResponse commandResponse = null;
+        try {
+            commandResponse = zyStationConnectDriver.sendCommand(command);
+            return commandResponse;
+        } finally {
+            BasStationOptService optService = SpringUtils.getBean(BasStationOptService.class);
+            List<ZyStationStatusEntity> statusListEntity = zyStationConnectDriver.getStatus();
+            ZyStationStatusEntity matched = null;
+            if (statusListEntity != null) {
+                for (ZyStationStatusEntity e : statusListEntity) {
+                    if (e.getStationId() != null && e.getStationId().equals(command.getStationId())) {
+                        matched = e;
+                        break;
+                    }
+                }
+            }
+            BasStationOpt basStationOpt = new BasStationOpt(
+                    command.getTaskNo(),
+                    command.getStationId(),
+                    new Date(),
+                    String.valueOf(command.getCommandType()),
+                    command.getStationId(),
+                    command.getTargetStaNo(),
+                    null,
+                    null,
+                    null,
+                    JSON.toJSONString(command),
+                    JSON.toJSONString(matched),
+                    1,
+                    JSON.toJSONString(commandResponse)
+            );
+            if (optService != null) {
+                optService.insert(basStationOpt);
+            }
+        }
+    }
+
+    @Override
+    public CommandResponse sendOriginCommand(String address, short[] data) {
+        return zyStationConnectDriver.sendOriginCommand(address, data);
+    }
+
+    @Override
+    public byte[] readOriginCommand(String address, int length) {
+        return zyStationConnectDriver.readOriginCommand(address, length);
+    }
+
+    private List<Integer> calcPathStationIds(Integer startStationId, Integer targetStationId) {
+        NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
+        if (navigateUtils == null) {
+            return new ArrayList<>();
+        }
+        List<NavigateNode> nodes = navigateUtils.calcByStationId(startStationId, targetStationId);
+        List<Integer> ids = new ArrayList<>();
+        for (NavigateNode n : nodes) {
+            JSONObject v = JSONObject.parseObject(n.getNodeValue());
+            if (v != null) {
+                ids.add(v.getInteger("stationId"));
+            }
+        }
+        return ids;
+    }
+
+    private void executeMoveWithSeg(StationCommand original) {
+        if(original.getCommandType() == StationCommandType.MOVE){
+            List<Integer> path = original.getNavigatePath();
+            if (path == null || path.isEmpty()) {
+                path = calcPathStationIds(original.getStationId(), original.getTargetStaNo());
+            }
+            if (path == null || path.isEmpty()) {
+                return;
+            }
+
+            int total = path.size();
+            List<Integer> segmentTargets = new ArrayList<>();
+            List<Integer> segmentEndIndices = new ArrayList<>();
+            int idx = 0;
+            while (idx < total) {
+                int end = Math.min(idx + 20, total) - 1;
+                segmentTargets.add(path.get(end));
+                segmentEndIndices.add(end);
+                idx = end + 1;
+            }
+
+            int segCursor = 0;
+            Integer currentTarget = segmentTargets.get(segCursor);
+            Integer currentEndIdx = segmentEndIndices.get(segCursor);
+            Integer currentStartIdx = 0;
+
+            StationCommand segCmd = new StationCommand();
+            segCmd.setTaskNo(original.getTaskNo());
+            segCmd.setStationId(original.getStationId());
+            segCmd.setTargetStaNo(original.getTargetStaNo());
+            segCmd.setCommandType(original.getCommandType());
+            segCmd.setPalletSize(original.getPalletSize());
+            segCmd.setNavigatePath(new ArrayList<>(path.subList(0, currentEndIdx + 1)));
+            sendCommand(segCmd);
+
+            boolean finished = false;
+            while (!finished) {
+                try {
+                    Integer currentStationId = findCurrentStationByTask(original.getTaskNo());
+                    if (currentStationId == null) {
+                        Thread.sleep(500);
+                        continue;
+                    }
+                    int currentIndex = path.indexOf(currentStationId);
+                    if (currentIndex < 0) {
+                        Thread.sleep(500);
+                        continue;
+                    }
+                    int remaining = total - currentIndex - 1;
+                    if (remaining <= 0) {
+                        finished = true;
+                        break;
+                    }
+                    int currentSegEndIndex = path.indexOf(segmentTargets.get(segCursor));
+                    int currentSegStartIndex = segCursor == 0 ? 0 : path.indexOf(segmentTargets.get(segCursor - 1)) + 1;
+                    int segLen = currentSegEndIndex - currentSegStartIndex + 1;
+                    int remainingSegment = Math.max(0, currentSegEndIndex - currentIndex);
+                    int thresholdSegment = (int) Math.ceil(segLen * 0.3);
+                    if (remainingSegment <= thresholdSegment && segCursor < segmentTargets.size() - 1) {
+                        segCursor++;
+                        currentEndIdx = segmentEndIndices.get(segCursor);
+                        currentStartIdx = segmentEndIndices.get(segCursor - 1) + 1;
+
+                        StationCommand nextCmd = new StationCommand();
+                        nextCmd.setTaskNo(original.getTaskNo());
+                        nextCmd.setStationId(original.getStationId());
+                        nextCmd.setTargetStaNo(original.getTargetStaNo());
+                        nextCmd.setCommandType(original.getCommandType());
+                        nextCmd.setPalletSize(original.getPalletSize());
+                        nextCmd.setNavigatePath(new ArrayList<>(path.subList(currentStartIdx, currentEndIdx + 1)));
+                        sendCommand(nextCmd);
+                    }
+                    Thread.sleep(500);
+                } catch (Exception e) {
+                    break;
+                }
+            }
+        }else {
+            sendCommand(original);
+        }
+    }
+
+    private Integer findCurrentStationByTask(Integer taskNo) {
+        try {
+            com.zy.asrs.service.DeviceConfigService deviceConfigService = SpringUtils.getBean(com.zy.asrs.service.DeviceConfigService.class);
+            if (deviceConfigService == null) {
+                return null;
+            }
+            List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<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());
+                if (t == null) {
+                    continue;
+                }
+                Map<Integer, StationProtocol> m = t.getStatusMap();
+                if (m == null || m.isEmpty()) {
+                    continue;
+                }
+                for (StationProtocol sp : m.values()) {
+                    if (sp.getTaskNo() != null && sp.getTaskNo().equals(taskNo) && sp.isLoading()) {
+                        return sp.getStationId();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java b/src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java
index 983b5db..e7546e2 100644
--- a/src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java
@@ -578,7 +578,7 @@
                             continue;
                         }
                         //鐢熸垚浠跨湡绔欑偣鏁版嵁
-                        StationCommand command = stationThread.getMoveCommand(9998, wrkMast.getSourceStaNo(), 0, 0);
+                        StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO, 9998, wrkMast.getSourceStaNo(), 0, 0);
                         MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                     }
                 }
diff --git a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
index 39c4396..4a4b2d2 100644
--- a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -15,6 +15,7 @@
 import com.zy.core.cache.SlaveConnection;
 import com.zy.core.enums.RedisKeyType;
 import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.StationCommandType;
 import com.zy.core.enums.WrkStsType;
 import com.zy.core.model.StationObjModel;
 import com.zy.core.model.Task;
@@ -107,7 +108,7 @@
                         continue;
                     }
 
-                    StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationId, targetStationId, 0);
+                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0);
                     if(command == null){
                         News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                         continue;
@@ -174,7 +175,7 @@
                         && stationProtocol.isLoading()
                         && stationProtocol.getTaskNo() == 0
                 ) {
-                    StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
+                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
                     if(command == null){
                         News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                         continue;
@@ -312,7 +313,7 @@
                                 continue;
                             }
 
-                            StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationProtocol.getStationId(), targetStationId, 0);
+                            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), targetStationId, 0);
                             if(command == null){
                                 News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                                 continue;
@@ -348,7 +349,7 @@
                         }
                     }else {
                         //杩愯鍫靛锛岄噸鏂拌绠楄矾绾�
-                        StationCommand command = stationThread.getMoveCommand(wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
+                        StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
                         if(command == null){
                             News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
                             continue;
diff --git a/src/main/webapp/components/DevpCard.js b/src/main/webapp/components/DevpCard.js
index 479306b..97b3367 100644
--- a/src/main/webapp/components/DevpCard.js
+++ b/src/main/webapp/components/DevpCard.js
@@ -40,6 +40,7 @@
                 <el-descriptions-item label="绌烘澘淇″彿">{{ item.emptyMk ? 'Y' : 'N' }}</el-descriptions-item>
                 <el-descriptions-item label="婊℃澘淇″彿">{{ item.fullPlt ? 'Y' : 'N' }}</el-descriptions-item>
                 <el-descriptions-item label="杩愯闃诲">{{ item.runBlock ? 'Y' : 'N' }}</el-descriptions-item>
+                <el-descriptions-item label="鍚姩鍏ュ簱">{{ item.enableIn ? 'Y' : 'N' }}</el-descriptions-item>
                 <el-descriptions-item label="鎵樼洏楂樺害">{{ item.palletHeight }}</el-descriptions-item>
                 <el-descriptions-item label="鏉$爜">{{ item.barcode }}</el-descriptions-item>
                 <el-descriptions-item label="鏁呴殰浠g爜">{{ item.error }}</el-descriptions-item>

--
Gitblit v1.9.1